# Solving "Sorted Union" / freeCodeCamp Algorithm Challenges

### 7/23/2020

Let's solve freeCodeCamp's intermediate algorithm scripting challenge, 'Sorted Union'.

### Starter Code

``````function uniteUnique(arr) {
return arr;
}

uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);
``````

### Instructions

Write a function that takes two or more arrays and returns a new array of unique values in the order of the original provided arrays.

In other words, all values present from all arrays should be included in their original order, but with no duplicates in the final array.

The unique numbers should be sorted by their original order, but the final array should not be sorted in numerical order.

Check the assertion tests for examples.

### Test Cases

``````uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]) should return [1, 3, 2, 5, 4].
uniteUnique([1, 2, 3], [5, 2, 1]) should return [1, 2, 3, 5].
uniteUnique([1, 2, 3], [5, 2, 1, 4], [2, 1], [6, 7, 8]) should return [1, 2, 3, 5, 4, 6, 7, 8].
``````

# Our Approach

We have a short set of instructions for this one. After reading and looking at the test cases,

• We have one input, `arr`, but there are more than one `arguments` in the function given.
• We must return an array.
• We have to create an array of the values of the arrays in `arguments`, but in the original order and also no duplicates.

To clarify it a little better, we can look at one of the test cases -

``````uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]) should return [1, 3, 2, 5, 4]

// 3 arrays in arguments
// 1 and 2 are in every array but we just take the one we see first
// first arg is [1,3,2] so we enter those values in that order in our new array
// moving on to the second array, 5 is new, so we can add that into the new array
// 2 and then 1 are already in so we do not want to add them in as they'd be duplicates
// 4 is new, lets add that
// the third array, [2,1], are already in the array so disregard
``````

So with that, let's start trying to solve this.

The first thing I'd like to work on is the arguments. Looking at the provided code and test cases, we have `arr`, but each test case has more than one array. How can we access all of the arrays?

``````function uniteUnique(arr) {
console.log(arr);
}

uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);
// [1, 3, 2]
// The console.log(arr) is only going to output the first array
``````

Enter in the `arguments` object. I always find the MDN web docs to be helpful.

"`arguments` is an `Array`-like object accessible inside functions that contains the values of the arguments passed to that function." - MDN

Looking at a little sample helps, let's use the above again -

``````function uniteUnique(arr) {
console.log(arr);
console.log(arguments);
}

uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);
//console.log(arr)  -- [1, 3, 2]
// console.log(arguments) -- { '0': [ 1, 3, 2 ], '1': [ 5, 2, 1, 4 ], '2': [ 2, 1 ] }
``````

`arguments` gives us all the values back in an object. For the sake of this challenge, I think it would be easier to work with these values in an array instead of an object so we can use the spread syntax.

``````function uniteUnique(arr) {
const arrArgs = [...arguments]
console.log(arrArgs);
}

uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);
// [ [ 1, 3, 2 ], [ 5, 2, 1, 4 ], [ 2, 1 ] ]
``````

So we now have an array of arrays not an object of arrays.

My next action is to create an empty array to hold our new array.

``````const union = [];
``````

We can now think about how we should loop through `arrArgs` and what to push into `union`.

So, we want to add unique values only and ensure we add them in the order we encounter them. Since there are subarrays in `arrArgs`, I think I would opt for a `for` loop and have to place another `for` loop inside to access the subarrays.

To check if the item already exists in our new array, we can use `indexOf()` as it is a good way to check.

Array.indexOf() on MDN

``````for (let i = 0; arrArgs.length; i++) {
for (let j = 0; arrArgs[i].length; j++) {
if (union.indexOf(arrArgs[i][j]) == -1) {
union.push(arrArgs[i][j])
}
}
}
``````

In the above, we are checking to see if each value exists in `union`. If it returns `true`, we can `push()` it into `union`. If the `if` statement returns false, we move on to the next item.

Ensure we return `union` and that should be all.

# Our Solution

``````function uniteUnique(arr) {
const arrArgs = [...arguments];
const union = [];
for (let i = 0; i < arrArgs.length; i++) {
for (let j = 0; j < arrArgs[i].length; j++) {
if (union.indexOf(arrArgs[i][j]) == -1) {
union.push(arrArgs[i][j]);
}
}
}
return union;
}
``````