Merge Arrays with JavaScript

By  on  

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!

Recent Features

  • By
    Chris Coyier’s Favorite CodePen Demos

    David asked me if I'd be up for a guest post picking out some of my favorite Pens from CodePen. A daunting task! There are so many! I managed to pick a few though that have blown me away over the past few months. If you...

  • By
    CSS Gradients

    With CSS border-radius, I showed you how CSS can bridge the gap between design and development by adding rounded corners to elements.  CSS gradients are another step in that direction.  Now that CSS gradients are supported in Internet Explorer 8+, Firefox, Safari, and Chrome...

Incredible Demos

  • By
    HTML5 download Attribute

    I tend to get caught up on the JavaScript side of the HTML5 revolution, and can you blame me?  HTML5 gives us awesome "big" stuff like WebSockets, Web Workers, History, Storage and little helpers like the Element classList collection.  There are, however, smaller features in...

  • By
    iPhone Click Effect Using MooTools or jQuery

    One thing I love about love about Safari on the iPhone is that Safari provides a darkened background effect when you click a link. It's the most subtle of details but just enforces than an action is taking place. So why not implement that...

Discussion

    • concat returns a new array, doesn’t merge into the first one.

    • Ilya

      Yes, it returns new array, but you didn’t say that in post

  1. Valtteri

    With ES6 spread operator:

    var array1 = [0, 1, 2];
    var array2 = [3, 4, 5];
    array1.push(...array2);
    

    Source: MDN

  2. Nikhil

    Why is

    Array.prototype.push.apply(array1, array2);

    different from

    Array.push.apply(array1, array2);

    , which returns

    [1,2,3]
  3. There’s a concat method for this purpose.

    • Again, concat creates a new array. My method in the post does not.

  4. Ryan Murphy

    I wish you posted this 2 days ago :) I went back and refactored.
    Thanks!

  5. Why not

    array2.push.apply(array1, array2);

    ?

    • Val

      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.

    • Ilya

      how do you prepend a string to variable? :)
      I mean how do you write the following:

      str = 'foo' + str;
      
  6. This can be shortened just a little:

    array1.push.apply(array1, array2);
    

    Although as mentioned above the ES6 spread operator is great for concatenation.

  7. chris-l

    If you miss for some reason array_merge, then you can do:

    var array_merge = Function.prototype.apply.bind(Array.prototype.push);

    Then you can use like this:

    array_merge(array1, array2);

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

  8. Berkana

    You could save yourself a bunch of typing by doing

    [].push.apply(array1, array2);
    

    since the empty array will look up the prototype chain to find the push method, then apply it.

    • IlyaVF

      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.

  9. Jay Doubleyou

    Thanks for sharing!

  10. Nick

    A new array via concat is preferable to a mutative merge!

  11. Ray

    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.

  12. 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.

  13. Thanks for sharing this trick!

  14. 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):

    var arr = [1,2];
    arr.push.apply(arr, _.range(0, 500000));
    
  15. IlyaVF

    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 and array2 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 or array1.push or array2.push or Array.prototype.push. The apply method will replace the context (this) for the method according to its first argument. Only Array.prototype.push is the fastest (there is no prototype chain lookup).

  16. Ctibor

    Thats really nice shortcut.. I love it :)

  17. Ajay
    array1 = array1.concat(array2);

    This serves the same output. So what is the difference between using this method and Array.prototype.push.apply(array1, array2)?

  18. Aaron

    “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.

    • IlyaVF

      I think by this statement the author meant something like this:

      var a = [1,2,3];
      var b = a;
      a = a.concat([4,5]);
      a
      // -> [1,2,3,4,5];
      b
      // -> [1,2,3]
      

      Whereas using push method _b_ would point to the same array as _a_.

  19. Adam

    This was covered previously on DWB: http://davidwalsh.name/combining-js-arrays

  20. noproblemo

    concat useful to flattening array , example :

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

    is there a better way ???

  21. push and pop add/remove elements from the end of the array unshift / shift — add/remove elements from the beginning of the array splice — add/remove elements from the specified location of the array.

  22. joe hoeller

    How do you make an array of arrays?

    $scope.result = [ ];
    
    //do stuff here to push the arrays into the above array so the result look like this:
    
    $scope.result = [  [1,2], [3,4], [5,6]  ];
    
  23. Brian Peacock

    Why not return Array.concat() out of a function?

        function mergeArrays() {
          return [].concat.apply([], arguments);
        }
    
        var arrA = [1,2,3,4,5];
        var arrB = [6,7,8,9,10];
        var arrC = ['eleven','twelve','thirteen'];
        
        arrA = mergeArrays(arrA, arrB, arrC);
        //-> arrA: [1,2,3,4,5,6,7,8,9,10,'eleven','twelve','thirteen']
    

    Just a thought.

    • Brian Peacock, Thanks alot for your code!!! It worked like charm!!!

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!