Intermediate Algorithm: Sorted Union -- filter function not working

Intermediate Algorithm: Sorted Union -- filter function not working
0

#1

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]);

#2

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?


#3

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.


#4

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


#5

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


#6

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.


#7

Oh! It should be the following:

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

Right?


#8

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

#9

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) {

#10

Wow! thanks to both of you. Very helpful.