What is the most efficient way to concatenate N arrays?

JavascriptArrays

Javascript Problem Overview


What is the most efficient way to concatenate N arrays of objects in JavaScript?

The arrays are mutable, and the result can be stored in one of the input arrays.

Javascript Solutions


Solution 1 - Javascript

If you're concatenating more than two arrays, concat() is the way to go for convenience and likely performance.

var a = [1, 2], b = ["x", "y"], c = [true, false];
var d = a.concat(b, c);
console.log(d); // [1, 2, "x", "y", true, false];

For concatenating just two arrays, the fact that push accepts multiple arguments consisting of elements to add to the array can be used instead to add elements from one array to the end of another without producing a new array. With slice() it can also be used instead of concat() but there appears to be no performance advantage from doing this.

var a = [1, 2], b = ["x", "y"];
a.push.apply(a, b);
console.log(a); // [1, 2, "x", "y"];

In ECMAScript 2015 and later, this can be reduced even further to

a.push(...b)

However, it seems that for large arrays (of the order of 100,000 members or more), the technique passing an array of elements to push (either using apply() or the ECMAScript 2015 spread operator) can fail. For such arrays, using a loop is a better approach. See https://stackoverflow.com/a/17368101/96100 for details.

Solution 2 - Javascript

[].concat.apply([], [array1, array2, ...])

edit: proof of efficiency: http://jsperf.com/multi-array-concat/7

edit2: Tim Supinie mentions in the comments that this may cause the interpreter to exceed the call stack size. This is perhaps dependent on the js engine, but I've also gotten "Maximum call stack size exceeded" on Chrome at least. Test case: [].concat.apply([], Array(300000).fill().map(_=>[1,2,3])). (I've also gotten the same error using the currently accepted answer, so one is anticipating such use cases or building a library for others, special testing may be necessary no matter which solution you choose.)

Solution 3 - Javascript

For people using ES2015 (ES6)

You can now use the Spread Syntax to concatenate arrays:

const arr1 = [0, 1, 2],
      arr2 = [3, 4, 5];

const result1 = [...arr1, ...arr2]; // -> [0, 1, 2, 3, 4, 5]

// or...

const result2 = [...arr2, ...arr1]; // -> [3, 4, 5, 0, 1, 2]

Solution 4 - Javascript

Use Array.prototype.concat.apply to handle multiple arrays' concatenation:

var resultArray = Array.prototype.concat.apply([], arrayOfArraysToConcat);

Example:

var a1 = [1, 2, 3],
    a2 = [4, 5],
    a3 = [6, 7, 8, 9];
Array.prototype.concat.apply([], [a1, a2, a3]); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

Solution 5 - Javascript

The concat() method is used to join two or more arrays. It does not change the existing arrays, it only returns a copy of the joined arrays.

array1 = array1.concat(array2, array3, array4, ..., arrayN);

Solution 6 - Javascript

New Answer

For array of multiple arrays and ES6, use

arr.flat();

For example:

const arr = [[1, 2, 3], [4, 5, 6], [7, 8 ,9]];
const newArr = arr.flat();
// output: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

This will work with node > 11 and modern browsers.


Old Answer

(leaving it here just in case it's needed for old node versions):

For array of multiple arrays and ES6, use

Array.prototype.concat(...arr);

For example:

const arr = [[1, 2, 3], [4, 5, 6], [7, 8 ,9]];
const newArr = Array.prototype.concat(...arr);
// output: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

Solution 7 - Javascript

If you are in the middle of piping the result through map/filter/sort etc and you want to concat array of arrays, you can use reduce

let sorted_nums = ['1,3', '4,2']
  .map(item => item.split(','))   // [['1', '3'], ['4', '2']]
  .reduce((a, b) => a.concat(b))  // ['1', '3', '4', '2']
  .sort()                         // ['1', '2', '3', '4']

Solution 8 - Javascript

solved like this.

let arr = [[1, 2], [3, 4], [5, 6]];
 console.log([].concat(...arr));

Solution 9 - Javascript

Now we can combine multiple arrays using ES6 Spread. Instead of using concat() to concatenate arrays, try using the spread syntax to combine multiple arrays into one flattened array. eg:

var a = [1,2];
var b = [3,4];
var c = [5,6,7];
var d = [...a, ...b, ...c];
// resulting array will be like d = [1,2,3,4,5,6,7]

Solution 10 - Javascript

Shorten with ES6.

new Set([].concat(...Array));

This does concat and unique the multiple arrays;

let Array = [
  ['vue','babel','npm','gulp','mysql','less','laravel'],
  ['jquery','react','js','css','wordpress','html','bootstrap'],
  ['vue','babel','npm','gulp','mysql','less','laravel'],
  ['angular','cms','js','css','graphql','nodejs','php'],
  ['severless','headless','js','css','design','photoshop','php'],
]

const Boom = new Set([].concat(...Array));


// This is not necessary 
let dStr = '';
Boom.forEach(e=>{
  dStr += e + ' ';
})
document.write(dStr);

<div class="result"></div>

Solution 11 - Javascript

Merge Array with Push:

const array1 = [2, 7, 4];
const array2 = [3, 5,9];
array1.push(...array2);
console.log(array1)

Using Concat and Spread operator:

const array1 = [1,2];
const array2 = [3,4];

// Method 1: Concat 
const combined1 = [].concat(array1, array2);

// Method 2: Spread
const combined2 = [...array1, ...array2];

console.log(combined1);
console.log(combined2);

Solution 12 - Javascript

Easily with the concat function:

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

Solution 13 - Javascript

You can use jsperf.com site to compare perfomance. Here is link to concat.

Added comparison between:

var c = a.concat(b);

and:

var c = [];
for (i = 0; i < a.length; i++) {
    c.push(a[i]);
}
for (j = 0; j < b.length; j++) {
    c.push(b[j]);
}

The second is almost 10 times slower in chrome.

Solution 14 - Javascript

Here is a function by which you can concatenate multiple number of arrays

function concatNarrays(args) {
    args = Array.prototype.slice.call(arguments);
    var newArr = args.reduce( function(prev, next) {
       return prev.concat(next) ;
    });
    
    return newArr;
}

Example -

console.log(concatNarrays([1, 2, 3], [5, 2, 1, 4], [2,8,9]));

will output

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

Solution 15 - Javascript

If you have array of arrays and want to concat the elements into a single array, try the following code (Requires ES2015):

let arrOfArr = [[1,2,3,4],[5,6,7,8]];
let newArr = [];
for (let arr of arrOfArr) {
    newArr.push(...arr);
}

console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];

Or if you're into functional programming

let arrOfArr = [[1,2,3,4],[5,6,7,8]];
let newArr = arrOfArr.reduce((result,current)=>{
    result.push(...current);
	return result;
});

console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];

Or even better with ES5 syntax, without the spread operator

var arrOfArr = [[1,2,3,4],[5,6,7,8]];
var newArr = arrOfArr.reduce((result,current)=>{
    return result.concat(current);
});
console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];

This way is handy if you do not know the no. of arrays at the code time.

Solution 16 - Javascript

try this:

i=new Array("aaaa", "bbbb");
j=new Array("cccc", "dddd");

i=i.concat(j);

Solution 17 - Javascript

where 'n' is some number of arrays, maybe an array of arrays . . .

var answer = _.reduce(n, function(a, b){ return a.concat(b)})

Solution 18 - Javascript

If there are only two arrays to concat, and you actually need to append one of arrays rather than create a new one, push or loop is the way to go.

Benchmark: https://jsperf.com/concat-small-arrays-vs-push-vs-loop/

Solution 19 - Javascript

if the N arrays are gotten from the database and not hardcoded, the i'll do it like this using ES6

let get_fruits = [...get_fruits , ...DBContent.fruit];

Solution 20 - Javascript

You can use this -

let array2d = [[1, 2, 3], [5, 4], [7, 8]];

let array1d = array2d.reduce((merged, block) => {
                          merged.push(...block); 
                          return merged; 
                     }, []);

console.log(array1d); // [1, 2, 3, 5, 4, 7, 8]

OR this which I liked from one of the answers above -

let array2d = [[1, 2, 3], [5, 4], [7, 8]];
console.log([].concat(...array2d)); // [1, 2, 3, 5, 4, 7, 8]

OR this which I discovered -

let array2d = [[1, 2, 3], [5, 4], [7, 8]];
console.log(array2d.join().split(',').map(Number); // [1, 2, 3, 5, 4, 7, 8]

Solution 21 - Javascript

It appears that the correct answer varies in different JS engines. Here are the results I got from the test suite linked in ninjagecko's answer:

  • [].concat.apply is fastest in Chrome 83 on Windows and Android, followed by reduce (~56% slower);
  • looped concat is fastest in Safari 13 on Mac, followed by reduce (~13% slower);
  • reduce is fastest in Safari 12 on iOS, followed by looped concat (~40% slower);
  • elementwise push is fastest in Firefox 70 on Windows, followed by [].concat.apply (~30% slower).

Solution 22 - Javascript

The fastest by a factor of 10 is to iterate over the arrays as if they are one, without actually joining them (if you can help it).

I was surprised that concat is slightly faster than push, unless the test is somehow unfair.

const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'];
const arr2 = ['j', 'k', 'l', 'i', 'm', 'n', 'o', 'p', 'q', 'r', 's'];
const arr3 = ['t', 'u', 'v', 'w'];
const arr4 = ['x', 'y', 'z'];

let start;

// Not joining but iterating over all arrays - fastest
// at about 0.06ms
start = performance.now()

const joined = [arr1, arr2, arr3, arr4];

for (let j = 0; j < 1000; j++) {
  let i = 0;
  while (joined.length) {
    // console.log(joined[0][i]);
    if (i < joined[0].length - 1) i++;
    else {
      joined.shift()
      i = 0;
    }
  }
}

console.log(performance.now() - start);

// Concating (0.51ms).
start = performance.now()

for (let j = 0; j < 1000; j++) {
  const a = [].concat(arr1, arr2, arr3, arr4);
}

console.log(performance.now() - start);

// Pushing on to an array (mutating). Slowest (0.77ms)
start = performance.now()

const joined2 = [arr1, arr2, arr3, arr4];

for (let j = 0; j < 1000; j++) {
  const arr = [];
  for (let i = 0; i < joined2.length; i++) {
    Array.prototype.push.apply(arr, joined2[i])
  }
}

console.log(performance.now() - start);

You can make the iteration without joining cleaner if you abstract it and it's still twice as fast:

const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'];
const arr2 = ['j', 'k', 'l', 'i', 'm', 'n', 'o', 'p', 'q', 'r', 's'];
const arr3 = ['t', 'u', 'v', 'w'];
const arr4 = ['x', 'y', 'z'];

function iterateArrays(arrays, onEach) {
  let i = 0;
  while (joined.length) {
    onEach(joined[0][i]);
    if (i < joined[0].length - 1) i++;
    else {
      joined.shift();
      i = 0;
    }
  }
}

// About 0.23ms.
let start = performance.now()

const joined = [arr1, arr2, arr3, arr4];

for (let j = 0; j < 1000; j++) {
  iterateArrays(joined, item => {
    //console.log(item);
  });
}

console.log(performance.now() - start);

Solution 23 - Javascript

You can check this blog, here the performance for both push() and concat() has been compared. Also custom functions are made which performs better in specific scenario.

https://dev.to/uilicious/javascript-array-push-is-945x-faster-than-array-concat-1oki

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLeonidView Question on Stackoverflow
Solution 1 - JavascriptTim DownView Answer on Stackoverflow
Solution 2 - JavascriptninjageckoView Answer on Stackoverflow
Solution 3 - JavascriptDuncan LukkenaerView Answer on Stackoverflow
Solution 4 - JavascriptBurneeView Answer on Stackoverflow
Solution 5 - JavascriptdogbaneView Answer on Stackoverflow
Solution 6 - JavascriptDavidView Answer on Stackoverflow
Solution 7 - JavascriptartnikproView Answer on Stackoverflow
Solution 8 - JavascriptTh1View Answer on Stackoverflow
Solution 9 - JavascriptchinmayanView Answer on Stackoverflow
Solution 10 - JavascriptronaldtgiView Answer on Stackoverflow
Solution 11 - JavascriptZobia KanwalView Answer on Stackoverflow
Solution 12 - JavascriptDmitri FarkovView Answer on Stackoverflow
Solution 13 - JavascriptgorView Answer on Stackoverflow
Solution 14 - JavascriptKoushik DasView Answer on Stackoverflow
Solution 15 - JavascriptnoobView Answer on Stackoverflow
Solution 16 - JavascriptJAiroView Answer on Stackoverflow
Solution 17 - JavascriptrashadbView Answer on Stackoverflow
Solution 18 - JavascriptDanView Answer on Stackoverflow
Solution 19 - JavascriptAkinnifesi DamilolaView Answer on Stackoverflow
Solution 20 - JavascriptfiniteEffortView Answer on Stackoverflow
Solution 21 - JavascriptBenWView Answer on Stackoverflow
Solution 22 - JavascriptDominicView Answer on Stackoverflow
Solution 23 - JavascriptSatyam RaiView Answer on Stackoverflow