JavaScript:如何将整个列表添加到数组中?

44

有没有内置的方法可以像这样将一个列表追加到另一个列表中:

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

concat()做了类似的事情,但返回结果。我想要像push()一样修改现有列表的内容。


5个回答

65

push 能够工作,但你还需要使用 apply

var a = [1,2,3];
a.push.apply(a, [4,5])

1
我认为应该使用 Array.prototype.push.apply - lonesomeday
@lonesomeday:你想得对。a.push.apply 也可以。我显然两者都用了一下。 - outis
@Kooilnc:apply的MDC文档(在答案中链接)应该已经涵盖了它。阅读一下,如果需要更多帮助,请告诉我。 - outis
没问题,忘记 argsArray 就好了。 - KooiInc
1
它比较简洁(即不使用数组名称两次),但仍然比使用Array.prototyp.push.apply()更短,就是使用[].push.apply()。根据JSPerf测试“[concat vs push.apply](http://jsperf.com/concat-vs-push-apply/11)”,它也非常高效。 - zrajm

33
如果您正在使用ES6,您可以使用展开运算符。
例如:
listOne = [1,2,3]
listTwo = [4,5,6]
listTwo.push(...listOne)

24
var list = [1, 2];

人们已经向您展示了以下方法:

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

但是我想告诉你关于 ES6扩展运算符: list.push(...[3, 4]);.

请记住,目前并不是所有浏览器都支持它(您可以使用转换器)。


我发现,如果你的数组非常大,而你只插入了大约5-20个元素,那么list.push.apply方法会极大地提高速度。 - Aloso
@Aloso 谢谢,您可以发布一个带有相应基准测试的答案(看到“极快”和“非常大”背后的数字会很好)。 - Salvador Dali
我认为这并不值得一个完整的回答。但是,我制作了一个 jsperf 用于测试速度: https://jsperf.com/array-vs-linkedlist-concat - Aloso
好的,这还有更多内容,所以我会添加一个答案。 - Aloso

5
因为我刚刚写了一个Web应用程序,其中需要连接很多数组而且性能至关重要,所以我在这个jsperf上测试了哪种方法最快。结果非常有趣。
在我的测试中,我向10,000个元素的列表或数组添加了10个元素。
以下是测试案例,从最快到最慢排序。结果是在Chrome 62中测量的,但Firefox 47的表现类似:
  • 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);
    
很遗憾,如果您想将一个数组/列表连接到多个LinkedList中,LinkedList版本无法使用。如果在每次连接操作之前必须将数组复制到LinkedList中,则也没有任何好处。因此,对我来说,胜利者是for循环

不使用Array.prototype.push.apply的原因之一是,如果连接的数组太大,则会失败。根据此答案,Firefox中连接的数组不能超过500,000个元素,Chrome中不能超过150,000个元素。

我排除了展开运算符,因为它并不被所有浏览器支持。在Chrome中,它的速度与Array.prototype.push.apply差不多,在Firefox中略慢。


4
这样怎么样:
var a = [1, 2, 3];
a = a.concat([4, 5]);
// a is now [1, 2, 3, 4, 5]

只是一个接一个地推送它们不是更有效吗? - shoosh
@shoosh,是的,可能会更有效率。 - Darin Dimitrov
在连接字符串之前,请考虑以下代码:var b = a; 变量a发生变化,但b仍然是1、2、3。示例 - gor
哇!使用 concat 竟然效率如此低下![http://jsperf.com/concat-vs-push-apply/10] - zrajm
4
两年后,Chrome 37和IE11都报告concat比push apply快67%... - stefan.s
这是错误的。a.concat不会修改数组 - 代码var a = [1, 2, 3]; var b = a; a = a.concat([4, 5]);导致a不引用与b相同的对象,而b的对象没有[4, 5] - wizzwizz4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接