How to extend an existing JavaScript array with another array, without creating a new array
似乎没有办法用另一个数组来扩展现有的javascript数组,即模仿Python的
我希望实现以下目标:
| 1 2 3 4 5 6 7 | >>> a = [1, 2] [1, 2] >>> b = [3, 4, 5] [3, 4, 5] >>> SOMETHING HERE >>> a [1, 2, 3, 4, 5] | 
我知道有一个
注意:这不是如何将某些内容附加到数组的副本?--这里的目标是将一个数组的全部内容添加到另一个数组中,并"就地"执行,即不复制扩展数组的所有元素。
| 1 | >>> a.push(...b) | 
如果您的浏览器不支持ecmascript 6,您可以使用
| 1 | >>> a.push.apply(a, b) | 
或者,如果你觉得更清楚的话:
| 1 | >>> Array.prototype.push.apply(a,b) | 
请注意,如果数组
update 2018:a better answer is a newer one of mine:
对于那些只搜索"javascript数组扩展"并到达这里的用户,您可以很好地使用
| 1 2 | var a = [1, 2, 3]; a = a.concat([5, 4, 3]); | 
concat将返回新数组的副本,因为线程启动程序不需要。但是你可能不在乎(当然对于大多数用途来说,这是可以的)。
还有一些很好的ecmascript 6糖,以spread operator的形式:
| 1 2 | const a = [1, 2, 3]; const b = [...a, 5, 4, 3]; | 
(它也复制。)
您应该使用基于循环的技术。本页上基于使用
一个相当简单的基于循环的实现是:
| 1 2 3 4 | 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); } | 
然后可以执行以下操作:
| 1 2 3 | var a = [1,2,3]; var b = [5,4,3]; a.extend(b); | 
Dzinx的回答(使用push.apply)和其他基于
当以大数组作为第二个参数调用"function.prototype.apply"时,由于超出了调用堆栈大小,因此发生错误。(MDN注意到使用function.prototype.apply超过调用堆栈大小的危险-请参阅标题为"应用和内置函数"的部分。)
为了与本页上的其他答案进行速度比较,请查看这个JSperf(感谢eaterofcode)。基于循环的实现在速度上与使用
有趣的是,如果您要附加的数组是稀疏的,那么上面基于
顺便说一下,别被诱惑了(就像我以前那样!)要进一步缩短foreach实现,请执行以下操作:
| 1 2 3 | Array.prototype.extend = function (array) { array.forEach(this.push, this); } | 
因为这会产生垃圾结果!为什么?因为
我觉得现在最优雅的是:
| 1 | arr1.push(...arr2); | 
MDN关于Spread Operator的文章在ES2015(ES6)中提到了这种甜蜜的方式:
A better push
Example: push is often used to push an array to the end of an existing
array. In ES5 this is often done as:
2
3
4
var arr2 = [3, 4, 5];
// Append all items from arr2 onto arr1
Array.prototype.push.apply(arr1, arr2);In ES6 with spread this becomes:
2
3
var arr2 = [3, 4, 5];
arr1.push(...arr2);
请注意,根据jcdude的回答,
在javascript中,首先是几个关于
The
apply() method calls a function with a giventhis value, and
arguments provided as an array.
push需要向数组中添加一个项列表。但是,
假设您有这些数组:
| 1 2 | var a = [1, 2, 3, 4]; var b = [5, 6, 7]; | 
只需这样做:
| 1 | Array.prototype.push.apply(a, b); | 
结果将是:
| 1 | a = [1, 2, 3, 4, 5, 6, 7]; | 
同样的事情也可以在ES6中使用如下的排列运算符("
| 1 | a.push(...b); //a = [1, 2, 3, 4, 5, 6, 7]; | 
更短更好,但目前所有浏览器都不完全支持。
另外,如果要将所有内容从数组
| 1 2 3 | while(b.length) { a.push(b.shift()); } | 
结果如下:
| 1 2 | a = [1, 2, 3, 4, 5, 6, 7]; b = []; | 
如果您想使用jquery,这里有$.merge()。
例子:
| 1 2 3 | a = [1, 2]; b = [3, 4, 5]; $.merge(a,b); | 
结果:a=
我喜欢上面描述的
| 1 2 3 4 | Array.prototype.append = function(array) { this.push.apply(this, array) } | 
像这样使用
| 1 2 3 4 | a = [1,2] b = [3,4] a.append(b) | 
使用
| 1 2 3 4 5 | b.unshift(b.length) b.unshift(a.length) Array.prototype.splice.apply(a,b) b.shift() // Restore b b.shift() // | 
但是,尽管它比
此解决方案对我有效(使用ecmascript 6的spread运算符):
| 1 2 3 4 5 6 7 | let array = ['my', 'solution', 'works']; let newArray = []; let newArray2 = []; newArray.push(...array); // Adding to same array newArray2.push([...array]); // Adding as child/leaf/sub-array console.log(newArray); console.log(newArray2); | 
您可以创建一个polyfill进行扩展,如下所示。它将添加到数组中;就位并返回自身,以便您可以链接其他方法。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | if (Array.prototype.extend === undefined) { Array.prototype.extend = function(other) { this.push.apply(this, arguments.length > 1 ? arguments : other); return this; }; } function print() { document.body.innerHTML += [].map.call(arguments, function(item) { return typeof item === 'object' ? JSON.stringify(item) : item; }).join(' ') + ' '; } document.body.innerHTML = ''; var a = [1, 2, 3]; var b = [4, 5, 6]; print('Concat'); print('(1)', a.concat(b)); print('(2)', a.concat(b)); print('(3)', a.concat(4, 5, 6)); print(' Extend'); print('(1)', a.extend(b)); print('(2)', a.extend(b)); print('(3)', a.extend(4, 5, 6)); | 
| 1 2 3 4 | body { font-family: monospace; white-space: pre; } | 
我能看到非常好的答案,这取决于你的数组大小,你的要求和目标。它可以用不同的方式来完成。
我建议使用javascript for循环:
| 1 2 3 4 5 6 | var a = [1, 2]; var b = [3, 4, 5]; for (i = 0; i < b.length; i++) { a.push(b[i]); } | 
| 1 | Array [ 1, 2, 3, 4, 5 ] | 
然后你就可以做你自己的功能了:
| 1 2 3 4 5 6 | function extendArray(a, b){ for (i = 0; i < b.length; i++) { a.push(b[i]); } return a; } | 
| 1 | Array [ 1, 2, 3, 4, 5 ] | 
组合答案…
| 1 2 3 4 5 6 7 8 9 | Array.prototype.extend = function(array) { if (array.length < 150000) { this.push.apply(this, array) } else { for (var i = 0, len = array.length; i < len; ++i) { this.push(array[i]); }; } } | 
合并两个以上数组的另一种解决方案
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | var a = [1, 2], b = [3, 4, 5], c = [6, 7]; // Merge the contents of multiple arrays together into the first array var mergeArrays = function() { var i, len = arguments.length; if (len > 1) { for (i = 1; i < len; i++) { arguments[0].push.apply(arguments[0], arguments[i]); } } }; | 
然后调用并打印为:
| 1 2 | mergeArrays(a, b, c); console.log(a) | 
输出为:
对于>150000条记录,使用
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | if (!Array.prototype.extend) { Array.prototype.extend = function(arr) { if (!Array.isArray(arr)) { return this; } for (let record of arr) { this.push(record); } return this; }; } | 
答案非常简单。
| 1 2 3 4 5 6 7 8 9 10 11 | >>> a = [1, 2] [1, 2] >>> b = [3, 4, 5] [3, 4, 5] >>> SOMETHING HERE (The following code will combine the two arrays.) a = a.concat(b); >>> a [1, 2, 3, 4, 5] | 
concat的作用非常类似于javascript字符串串联。它将返回您在调用函数的数组末尾放入concat函数的参数的组合。关键是您必须将返回值赋给一个变量,否则它会丢失。例如
| 1 | a.concat(b);  <--- This does absolutely nothing since it is just returning the combined arrays, but it doesn't do anything with it. | 
超级简单,不依赖于扩散运算符或应用,如果这是一个问题。
| 1 | b.map(x => a.push(x)); | 
在对此进行了一些性能测试之后,它的速度非常慢,但回答了有关不创建新数组的问题。concat的速度明显更快,甚至jquery的
https://jspef.com/merge-arrays19b/1