Merge Arrays with JavaScript
Merging arrays is a fairly common occurrence. I remember when I worked a lot with PHP I would use array_merge()
all the time. I found myself merging arrays often when handling form submission.
JavaScript has a simple, native function for merging arrays (concat
) but it produces a new array. Since JavaScript vars are passed by reference, concat
may mess up a reference. If you want to merge a second array into an existing first array, you can use this trick:
var array1 = [1, 2, 3]; var array2 = [4, 5, 6]; Array.prototype.push.apply(array1, array2); console.log(array1); // is: [1, 2, 3, 4, 5, 6]
Using an Array.prototype
method, push
in this case, allows you to merge the second array into the first. The alternative is iterating through the second array and using push
on the first array. This shortcut is niiiiiiiiiice!
Why not https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/concat ?
concat
returns a new array, doesn’t merge into the first one.Yes, it returns new array, but you didn’t say that in post
With ES6 spread operator:
Source: MDN
Why is
different from
, which returns
there is no
Array.push
It’s only in Firefox and not standard (proposed here but no news since: http://wiki.ecmascript.org/doku.php?id=strawman:array_statics ).
Anyway, you can use `
… you can use
There’s a
concat
method for this purpose.Again,
concat
creates a new array. My method in the post does not.I wish you posted this 2 days ago :) I went back and refactored.
Thanks!
Same here. I have refactored it as well. I used to use this tool: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/concat
But it created new arrays instead of merging them. Thanks to this article, I won’t have to use this tool again.
Nice work David.
Preston
Why not
?
I guess that’s just a matter of taste. I personally wouldn’t like to to reference the same variable twice in the same line.
how do you prepend a string to variable? :)
I mean how do you write the following:
This can be shortened just a little:
Although as mentioned above the ES6 spread operator is great for concatenation.
If you miss for some reason
array_merge
, then you can do:Then you can use like this:
(IMHO, using concat is better. Returning a new array instead of changing one of the arguments is more “functional”. But of course, I’m pretty sure there are cases where changing an existing array may be required)
You could save yourself a bunch of typing by doing
since the empty array will look up the prototype chain to find the
push
method, thenapply
it.Although the result is the same, but in your variate there is are two extra steps of creating a new array and looking through the prototype chain.
Thanks for sharing!
A new array via
concat
is preferable to a mutative merge!I tend to discourage this type of thing as opposed to properly using
concat
. As it can be difficult, at first glance for other devs to figure out what the intent is.I think that a lot of people are missing the point.
concat
and[].push.apply(array1, array2)
would be used in different situations.concat
is used if you *want* a new array – immutability is an example.[].push.apply(array1, array2)
– is used if you need to maintain a reference to the primary array. e.g. it’s a property of an object that you’re iterating through and is referenced elsewhere.Thanks for sharing this trick!
Beware of apply. A too large array2 will result in a Uncaught RangeError: Maximum call stack size exceeded.
E.g. this will crash in google chrome (with lodash):
This is a nice trick. Just wanted to add some explanation why this is working.
The
push
method expects comma separated arguments to be used as a new elements for the array to push to.The
apply
method expects two arguments: the first one to be used as a context (this
) for the method, and the second one as an array of arguments to be applied to the method.So the trick is that when you use _apply_ the _array1_ is used a context for
push
method andarray2
in the original example will be used as an array of arguments for the push method.And it does not matter if you use
[].push
orarray1.push
orarray2.push
orArray.prototype.push
. Theapply
method will replace the context (this
) for the method according to its first argument. OnlyArray.prototype.push
is the fastest (there is no prototype chain lookup).Thats really nice shortcut.. I love it :)
This serves the same output. So what is the difference between using this method and
Array.prototype.push.apply(array1, array2)
?“Since JavaScript vars are passed by reference, concat may mess up a reference.”
What does this mean? Mutating a reference IS messing up the reference. This is a performance optimization that could lead to subtle bugs. In other words, you should probably stick to concat unless you have a good reason for mutation.
I think by this statement the author meant something like this:
Whereas using push method _b_ would point to the same array as _a_.
This was covered previously on DWB: http://davidwalsh.name/combining-js-arrays
concat useful to flattening array , example :
is there a better way ???
push
andpop
add/remove elements from the end of the arrayunshift
/shift
— add/remove elements from the beginning of the arraysplice
— add/remove elements from the specified location of the array.How do you make an array of arrays?
Why not return
Array.concat()
out of a function?Just a thought.
Brian Peacock, Thanks alot for your code!!! It worked like charm!!!