Intermediate Algorithm: Sorted Union -- filter function not working

Ok. I don’t know why this isn’t working. Can someone enlighten me?

function uniteUnique(arr) {
  arr = Array.prototype.slice.call(arguments);
  arr = [].concat.apply(arr);
  arr = arr.filter( function (item, pos) {
    return arr.indexOf(item) == pos;
  });

  return arr;
}

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

The line above creates the following array.

[ [ 1, 3, 2 ], [ 5, 2, 1, 4 ], [ 2, 1 ] ]

The second line creates the following array:

[ [ 1, 3, 2 ], [ 5, 2, 1, 4 ], [ 2, 1 ] ]

And finally, the line containing the filter method creates the following array which gets returned.

[ [ 1, 3, 2 ], [ 5, 2, 1, 4 ], [ 2, 1 ] ]

What are you expecting the 2nd line and the filter method line to do exactly?

I was expecting the first line to create the array that you wrote.

I am expecting the second line to flatten out the array (remove the nested array).

I am expecting the filter function to remove any duplicates but leave the first occurrence.

When you say flatten out the array, can you show what you wanted arr to look like after the second line executes?

[ 1, 3, 2,5, 2, 1, 4 , 2, 1 ]

Your use of apply is close, but you will need two arguments. The first argument should be would what you want this to be. In this case this should be a literal array. The second argument is the array of elements you want to apply to this via concat. See if you can figure out the correct syntax now.

Oh! It should be the following:

arr = [].concat.apply([], arr);

Right?

Yep. You can break it down conceptually like this:

['placeholder'].concat.apply(['original', 'array'], [['arrays'], ['to'], ['concatenate']]);
// => ["original", "array", "arrays", "to", "concatenate"]

Note that the placeholder array is discarded (regardless of whether or not it contains any data) — the only reason we need it is as shorthand to get that concat method from the array prototype:

Array.prototype.concat === [].concat;
// => true

Yes you can do that. However, there is another way which is simpler.

Use the spread operator like:

arr = [].concat(...arr);

Speaking of simpler, you can replace the following:

arr = Array.prototype.slice.call(arguments);

by using the rest syntax in the parameter section of the function:

function uniteUnique(...arr) {

Wow! thanks to both of you. Very helpful.