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

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


当前回答

最快的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);

其他回答

如果要连接两个以上的数组,为了方便和可能的性能,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()方法用于连接两个或多个数组。它不会更改现有数组,只返回已连接数组的副本。

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

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

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

对于使用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]

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

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]