Confused. don't understand - [].concat.apply([],arr)

Confused. don't understand - [].concat.apply([],arr)
0

#1

Hi,

I’m on one of the algorithm challenges - “Sorted Union”, where one of the things we have to do is flatten an array of arrays.

E.g.
> var arr = [[0],[1],[2],[3],[4],[5]];
> var rslt = Array.concat.apply([],arr);
> console.log(rslt) // [0,1,2,3,4,5]

It seems straightforward but I’m missing something. How does this work?
I looked at the documentation for Array.prototype.concat() on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat, but still didn’t understand the above code.

I understand a.concat(b) produces [a,b] (e.g. [1,2].concat([3,4]) === [1,2,3,4]),
but how/why does it flatten the array one level?

i.e. Why is Array.concat.apply( [], [1, [2], [3, 4]] ) === Array.concat(1, [2], [3,4]) ??? (result is [1,2,3,4]) in both cases

Thanks,

  • Jay

#2

there is also apply method used there.

Array.prototype.concat.apply([1,2], [[3],[4]]) === [1,2,3,4]
is equal to
[1,2].concat([3],[4]) === [1,2,3,4]
or in es2015
[1,2].concat(...[[3],[4]]) === [1,2,3,4]

read more:
apply
spread operator


#3

Here is a link that might help you: https://www.reddit.com/r/learnjavascript/comments/3coq4g/how_does_concatapply_work/

It’s a property from concat() that does the heavy lifting, “apply” just executes the method.


#5

So what you’re saying is that the concat function on arrays (i.e. Array.protype.concat ([x]) will always reduce [x] by 1 array level i.e. if arr = [1,2] it will become 1,2 and if arr = [[1,2]] it will become [1,2]).

If I understand correctly, this is a feature of the JavaScript “concat” function - i.e. this happens automatically - but only when using apply to call the function.
So, Array.prototype.concat.apply(this, [x]) === this.concat([x]), where “this” is the first argument to the concat function.

Is my understanding correct?

Interesting, I have not seen this feature in other languages.

Thank you @marzelin and @Selhar1


#6

Ahh, thanks @MarkoN95, this makes more sense now.


#8

Ok, I think I got it.

Array.prototype.concat.call (this, [x]) === this.concat([x]),

and

Array.prototype.concat.apply (this, [x]) === this.concat(x).

And this is so because “apply” takes an array of arguments and treats each element of that array as a single argument.

So, an unintended consequence of “apply” is to unravel one level of the array - and this has absolutely nothing to do with the concat function which simply concatenates 2 values.

Sorry if I’m beinig overly redundant and simplistic in my understanding (still trying to learn JavaScript) :slight_smile:


#10

Thanks for the link Selhar1.
In a few words:

Apply Structure: myFunction.apply(thisVal,argsArray):

  • myFunction: Just the function to be executed.
  • thisVal: The context.
  • argsArray: The arguments from myFunction. Where argsArray = [arg1,arg2,arg3,…]

myFunction.apply(thisVal,argsArray) == thisVal.myFunction(arg1,arg2,arg3,…)

Array.prototype.concat([],[[1,2],[3,4]]) == [ ].concat([1,2],[3,4])

A new use for Apply :wink: