如何在不创建新数组的情况下用另一个数组扩展现有的JavaScript数组

如何在不创建新数组的情况下用另一个数组扩展现有的JavaScript数组

似乎没有一种方法可以用另一个数组扩展现有的JavaScript数组,即模拟Python的extend方法。

我要做到以下几点:

>>> a = [1, 2]

[1, 2]

>>> b = [3, 4, 5]

[3, 4, 5]

>>> SOMETHING HERE

>>> a

[1, 2, 3, 4, 5]

我知道有一个a.concat(b)方法,但是它创建一个新数组,而不是简单地扩展第一个数组。我想要一种高效的算法a明显大于b(即不复制的a).

注:这是不是复制品如何将某物附加到数组中?-此处的目标是将一个数组的全部内容添加到另一个数组中,然后“就位”,即不复制扩展数组的所有元素。


翻阅古今
浏览 376回答 3
3回答

慕桂英3389331

这个.push方法可以使用多个参数。您可以使用扩展算子将第二个数组的所有元素作为参数传递给.push:>>> a.push(...b)如果浏览器不支持ECMAScript 6,则可以使用.apply相反:>>> a.push.apply(a, b)或者,如果你觉得更清楚的话:>>> Array.prototype.push.apply(a,b)请注意,如果数组出现堆栈溢出错误,所有这些解决方案都将失败。b太长了(根据浏览器的不同,大约有10万个元素开始出现问题)。如果你不能保证b很短,您应该使用另一个答案中描述的基于循环的标准技术。

郎朗坤

更好的答案是我的新答案: a.push(...b)..不要再投这个票了,因为它从来没有真正回答过这个问题,但这是一次2015年的黑客攻击,围绕着谷歌的第一次攻击:)对于那些简单地搜索“JavaScript数组扩展”并来到这里的人,您可以很好地使用Array.concat.var a = [1, 2, 3];a = a.concat([5, 4, 3]);CONAT将返回一个新数组的副本,这是线程启动程序不想要的。但你可能不在乎(当然,对于大多数的用途,这都会很好)。也有一些不错的ECMAScript 6糖用于这个形式的扩展操作符:const a = [1, 2, 3];const b = [...a, 5, 4, 3];(它也是复制的。)

慕沐林林

你应该使用基于循环的技术。此页面上基于以下方法的其他答案:.apply对于大型数组,可能会失败。一个相当简洁的基于循环的实现是:Array.prototype.extend = function (other_array) {     /* You should include a test to check whether other_array really is an array */     other_array.forEach(function(v) {this.push(v)}, this);}然后,您可以执行以下操作:var a = [1,2,3];var b = [5,4,3];a.extend(b);DzinX的回答(使用push.application)和其他.apply当我们所附加的数组很大时,基于方法就会失败(测试表明,对我来说,Chrome中的>15万个条目,Firefox中的>500万个条目)。您可以看到这个错误发生在这个jsperf.当调用‘Function.Prototype.Apply’时,会出现错误,因为调用堆栈的大小超过了‘Function.Prototype.Apply’,而第二个参数(MDN有一个关于使用功能.原型.应用-见题为“应用和内置功能”的一节)。若要与此页上的其他答案进行速度比较,请查看这个jsperf(感谢EaterOfCode)。基于循环的实现在速度上与使用Array.push.apply,但往往比Array.slice.apply.有趣的是,如果所附加的数组是稀疏的,则forEach基于以上的方法可以充分利用稀疏性,优于传统的方法。.apply基于方法这个jsperf如果你想自己测试的话。顺便说一句,不要被诱惑(就像我一样!)进一步缩短forEach实现如下:Array.prototype.extend = function (array) {     array.forEach(this.push, this);}因为这会产生垃圾结果!为什么?因为Array.prototype.forEach为它调用的函数提供三个参数-它们是:(元素_值、元素_索引、源_数组)。的每一次迭代,所有这些都将被推入到第一个数组中。forEach如果你用“forEach(这个,推,这个)”!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript