连接N个数组最有效的方法是什么?

在JavaScript中连接N个对象数组的最有效的方法是什么?

数组是可变的,结果可以存储在一个输入数组中。

320578 次浏览

concat()方法用于连接两个或多个数组。它不会更改现有数组,只返回已连接数组的副本。

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

轻松使用concat函数:

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

试试这个:

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


i=i.concat(j);

你可以使用jsperf.com site来比较性能。这里是concat的链接。

增加了以下之间的比较:

var c = a.concat(b);

和:

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

第二款在镀铬的情况下几乎要慢10倍。

如果你要连接两个以上的数组,为了方便和可能的性能,concat()是最好的方法。

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];

对于仅仅连接两个数组,push接受多个由要添加到数组的元素组成的参数,这一事实可用于将一个数组的元素添加到另一个数组的末尾,而不产生新数组。对于slice(),它也可以用来代替concat(),而是这样做似乎没有性能优势

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

在ECMAScript 2015及以后的版本中,可以进一步简化为

a.push(...b)

然而,对于大型数组(100,000成员的数量级或更多),将元素数组传递给push的技术(使用apply()或ECMAScript 2015展开操作符)可能会失败。对于这样的数组,使用循环是更好的方法。详见https://stackoverflow.com/a/17368101/96100

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

编辑:效率证明:http://jsperf.com/multi-array-concat/7

edit2: Tim Supinie在注释中提到,这可能会导致解释器超过调用堆栈大小。这可能取决于js引擎,但我也得到了“最大调用堆栈大小超过”在Chrome上至少。测试用例:[].concat.apply([], Array(300000).fill().map(_=>[1,2,3]))。(我使用目前接受的答案也得到了同样的错误,所以一个人正在预测这样的用例或为其他人构建一个库,无论您选择哪种解决方案,特殊的测试都是必要的。)

其中'n'是数组的个数,可能是数组的数组…

Var答案= _。Reduce (n, function(a, b){返回a.concat(b)})

使用Array.prototype.concat.apply来处理多个数组的连接:

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

例子:

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]

如果你正在通过map/filter/sort等管道输出结果,并且你想连接数组的数组,你可以使用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']

这是一个函数,通过它可以连接多个数组

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


return newArr;
}

的例子,

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

将输出

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

如果只有两个数组要连接,并且你实际上需要附加其中一个数组,而不是创建一个新的数组,则推或循环是正确的方法。

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

对于使用ES2015 (ES6)的用户

你现在可以使用扩展语法来连接数组:

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]

新回答

对于多个数组和ES6的数组,使用

arr.flat();

例如:

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 ]

这将与node >11和现代浏览器。


旧的答案

(把它留在这里,以防旧版本的节点需要它):

对于多个数组和ES6的数组,使用

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

例如:

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 ]

如果你有一个数组的数组,想要连接到一个数组的元素,尝试以下代码(要求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];

或者如果你喜欢函数式编程

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];

或者使用ES5语法更好,没有展开操作符

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];

如果你不知道不,这种方法很方便。数组的。

现在我们可以使用ES6 Spread组合多个数组。 不要使用concat()来连接数组,而是尝试使用spread语法将多个数组组合成一个扁平数组。 如:< / p >
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]

这样解决。

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

用ES6缩短。

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

这是concat独特的的多个数组;

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>

如果N个数组是从数据库中获得的,并且没有硬编码,i将使用ES6这样做

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

推动:合并数组

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

使用Concat扩展操作符:

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

似乎正确答案在不同的JS引擎中有所不同。下面是我从测试套件链接在ninjagecko的答案中得到的结果:

  • 在Windows和Android上的Chrome 83中,[].concat.apply最快,其次是reduce(慢56%);
  • 在Mac的Safari 13中,concat是最快的,其次是reduce(大约慢13%);
  • 在iOS的Safari 12中,reduce是最快的,其次是循环的concat(慢40%);
  • elementwise push在Windows上的Firefox 70中最快,其次是[].concat.apply(慢30%)。

最快的10倍是迭代数组,就像它们是一个数组一样,而不实际连接它们(如果可以的话)。

我很惊讶concat比push稍微快一点,除非测试不公平。

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

如果你抽象它,你可以让不加入的迭代更干净,它仍然是原来的两倍:

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

你可以用这个-

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]

或者从上面的一个答案中我喜欢这个-

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

或者我发现的这个

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

你可以看看这个博客,在这里push()和concat()的性能进行了比较。此外,定制函数在特定场景下表现更好。

< a href = " https://dev。To /uilicious/javascript-array-push-is-945x-faster-than-array-concat-1oki" rel="nofollow noreferrer">https://dev.to/uilicious/javascript-array-push-is-945x-faster-than-array-concat-1oki .