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

IT技术 javascript arrays
2021-01-23 04:16:41

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

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

6个回答

如果您要连接两个以上的数组,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

更简洁的方法是 a.push(...b);
2021-03-20 04:16:41
@dinvlad:没错,但仅限于 ES6 环境。我在答案中添加了注释。
2021-03-24 04:16:41
我相信您的测试可能有错误:a.concat(b)测试用例似乎不必要地复制数组a然后将其丢弃。
2021-03-30 04:16:41
@ninjagecko:你说得对。我更新了它:jsperf.com/concatperftest/6对于创建连接两个现有数组的新数组的特殊情况,它看起来concat()通常更快。对于将数组连接到现有数组的情况,push()是要走的路。我更新了我的答案。
2021-04-06 04:16:41
我可以证明,与简单的 concat 调用相比,使用 push.apply 方法扩展具有多个新数组的单个数组具有巨大的性能优势(~100 倍)。我正在处理 v8/node.js 中很长的整数短列表。
2021-04-06 04:16:41
[].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])). (我在使用当前接受的答案时也遇到了同样的错误,因此人们正在预测此类用例或为其他人构建库,无论您选择哪种解决方案,都可能需要进行特殊测试。)

Eydrian:我个人尽量避免使用扩展运算符,因为它非常低效,但我不确定这是因为实现不成熟,还是 es6 规范的语义需要一些更重的提升(即它永远不会变得更好) )。不过,在这种特殊情况下还没有运行任何基准测试。
2021-03-13 04:16:41
@c69:至少在 Chrome 上,它似乎与重复 .push(#,#,...,#) 的选择答案一样有效。jsperf.com/multi-array-concat Tim Down 选择的答案也可能有错误。此链接是按问题加入多个数组的性能比较(不仅仅是 2 个);测试了多种可能的长度。
2021-03-18 04:16:41
使用 ES6 和扩展运算符,它变得更加简单: [].concat(...[array1, array2, ...]) 好吧,后三个点有点不幸。前三个是传播算子 developer.mozilla.org/en/docs/Web/JavaScript/Reference/...
2021-03-21 04:16:41
IMO 这是“合并”n 个数组的最有效方法,做得好
2021-03-24 04:16:41
当 N 提前未知时,此答案特别有用,例如当您有一个任意长度的数组数组并且您希望它们全部连接时。
2021-04-06 04:16:41

对于使用 ES2015 (ES6) 的人

您现在可以使用 Spread 语法来连接数组:

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]
不幸的是,此链接不再有效:/
2021-03-18 04:16:41
这是多么有效?根据我的测试,对于包含对象的数组,这非常慢,请参阅:jsperf.com/array-concat-vs-array-push-vs-array-spread/1
2021-04-10 04:16:41

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

array1 = array1.concat(array2, array3, array4, ..., arrayN);
@VincentHoch-Dreiconcat专门用于在不改变原始数组的情况下创建新数组。如果你想更新array1,你必须使用array1.push(...array2, ...array3, ...array4)
2021-03-18 04:16:41
有时我讨厌 JavaScript 不修改原始数组。🙄
2021-04-08 04:16:41

使用 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]
我喜欢这个!使用可变数量的数组来连接很容易。+1
2021-04-08 04:16:41