44

Is there a built in way to append one list into another like so:

var a = [1,2,3];
a.append([4,5]);
// now a is [1,2,3,4,5];

concat() does something similar but returns the result. I want something that modifies the existing list like push()

shoosh
  • 76,898
  • 55
  • 205
  • 325
  • 1
    possible duplicate of [Javascript push array values into another array](http://stackoverflow.com/questions/4156101/javascript-push-array-values-into-another-array), [how to do a “flat push” in javascript?](http://stackoverflow.com/questions/4007744/how-to-do-a-flat-push-in-javascript) – outis Jan 30 '11 at 13:03
  • Does this answer your question? [How to extend an existing JavaScript array with another array, without creating a new array](//stackoverflow.com/q/1374126/90527) – outis May 28 '22 at 18:19

5 Answers5

65

push will work, but you also need to use apply.

var a = [1,2,3];
a.push.apply(a, [4,5])
outis
  • 75,655
  • 22
  • 151
  • 221
  • 1
    That needs to be `Array.prototype.push.apply`, I think. – lonesomeday Jan 30 '11 at 13:05
  • @lonesomeday: you think correctly. `a.push.apply` will also work. I apparently split the difference. – outis Jan 30 '11 at 13:08
  • @Kooilnc: the MDC documentation for `apply` (linked to in the answer) should cover it. Read it and let me know if you need more. – outis Jan 30 '11 at 13:12
  • it's ok, forgot about the *argsArray* – KooiInc Jan 30 '11 at 13:16
  • 1
    It's less redundant (i.e. not using the array name *twice*), but still shorter than using `Array.prototyp.push.apply()` is to use `[].push.apply()`. -- And according to the JSPerf test "[concat vs push.apply](http://jsperf.com/concat-vs-push-apply/11)" it's pretty efficient as well. – zrajm Nov 24 '12 at 19:03
32

If you are using ES6 you can use the spread operator

eg :-

listOne = [1,2,3]
listTwo = [4,5,6]
listTwo.push(...listOne)
Avindu Hewa
  • 1,608
  • 1
  • 15
  • 23
24
var list = [1, 2];

People already showed you how to do this with:

  1. push: list.push.apply(list, [3, 4]);
  2. concat: list = list.concat([4, 5]);

But I want to tell about ES6 spread operator: list.push(...[3, 4]);.

Keep in mind that currently not many browsers support it (you can use transpilers).

Salvador Dali
  • 214,103
  • 147
  • 703
  • 753
  • I found out that, if your array is very big and you insert only about 5-20 elements, the `list.push.apply` method is extremely much faster. – Aloso Nov 27 '17 at 18:58
  • @Aloso Thanks, you can post this as an answer with a corresponding benchmark (it would be nice to see the numbers behind "extremely much faster" and "very big" – Salvador Dali Nov 27 '17 at 22:26
  • I don't think that this deserves a whole answer. However, I made a jsperf for testing speed: https://jsperf.com/array-vs-linkedlist-concat – Aloso Nov 27 '17 at 22:28
  • Ok, there's more to it, so I will add an answer. – Aloso Nov 27 '17 at 22:46
4

Because I just wrote a web application where a lot of arrays have to be concatenated and where performance is critical, I tested which method is fastest in this jsperf. The results are quite interesting.

In my test, I add 10 elements to a list or array of 10,000 elements.

Here are the test cases, from fastest to slowest. Results are measured in Chrome 62, but Firefox 47 performs similarly:

  • LinkedList.prototype.concat: 90,313,485 ops/sec

    list.concat(concatList);
    // This function has to change only 1-2 refences
    
  • Array.prototype.push in a for loop: 3,794,962 ops/sec

    for (var i = 0, len = concatArr.length; i < len; i++) {
        array.push(concatArr[i]);
    }
    // Probably fastest in real life
    
  • Array.prototype.push.apply: 2,193,469 ops/sec

    array.push.apply(array, concatArr);
    
  • Array.prototype.concat: 22,701 ops/sec

    array = array.concat(concatArr);
    

Unfortunately, the LinkedList version doesn't work if you want to concat an array/list to multiple LinkedLists. It also has no benefit if an array has to be copied to a LinkedList before every concat operation. So, for me, the winner is the for loop.

One reason to not use Array.prototype.push.apply is that it fails if the concatenated array is too big. According to this answer, the concatenated array can't have more than 500,000 elements in Firefox and 150,000 elements in Chrome.

I excluded the spread operator because it is not supported by all browsers. In Chrome, it's about as fast as Array.prototype.push.apply, in Firefox it is a bit slower.

Aloso
  • 5,123
  • 4
  • 24
  • 41
4

How about this:

var a = [1, 2, 3];
a = a.concat([4, 5]);
// a is now [1, 2, 3, 4, 5]
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Wouldn't just pushing them one after the other be more efficient? – shoosh Jan 30 '11 at 12:58
  • @shoosh, yes, probably it would be more efficient. – Darin Dimitrov Jan 30 '11 at 13:00
  • consider following code before concatenating: var b = a; The variable a changes, but b is still 1, 2, 3. [example](http://jsfiddle.net/rg3sj/) – gor Jan 30 '11 at 13:14
  • Wow! Using `concat` is *bizzarely* inefficient! [http://jsperf.com/concat-vs-push-apply/10] – zrajm Nov 24 '12 at 14:50
  • 3
    Two years later Chrome 37 and IE11 both report concat as 67% faster than push apply... – stefan.s Oct 20 '14 at 11:44
  • This is **wrong**. `a.concat` does not modify the array - the code `var a = [1, 2, 3];var b = a;a = a.concat([4, 5]);` results in `a` not referencing the same object as `b`, and `b`'s object not having `[4, 5]`. – wizzwizz4 Jun 16 '17 at 20:07