Is there a better way than this to splice an array into another array in javascript
在javascript中,是否有更好的方法将数组拼接到另一个数组中
var string = 'theArray.splice('+start+', '+number+',"'+newItemsArray.join('","')+'");';
eval(string);
7 个解决方案
#1
120
You can use apply to avoid eval:
您可以使用apply来避免eval:
var args = [start, number].concat(newItemsArray);
Array.prototype.splice.apply(theArray, args);
The apply function is used to call another function, with a given context and arguments, provided as an array, for example:
apply函数用于调用另一个函数,该函数具有给定的上下文和参数(如数组):
If we call:
如果我们所说的:
var nums = [1,2,3,4];
Math.min.apply(Math, nums);
The apply function will execute:
应用函数将执行:
Math.min(1,2,3,4);
#2
26
UPDATE: ES6 version
更新:ES6版本
If your coding in ES6 you can use the "spread operator" (...)
如果您在ES6中编写代码,您可以使用“扩展操作符”(…)
array.splice(index, 0, ...arrayToInsert);
To learn more about the spread operator see mozilla documentation.
要了解有关扩展操作符的更多信息,请参阅mozilla文档。
The 'old' ES5 way
“老”ES5的方式
If you wrap the top answer into a function you get this:
如果你把上面的答案打包成一个函数,你会得到:
function insertArrayAt(array, index, arrayToInsert) {
Array.prototype.splice.apply(array, [index, 0].concat(arrayToInsert));
}
You would use it like this:
你可以这样使用它:
var arr = ["A", "B", "C"];
insertArrayAt(arr, 1, ["x", "y", "z"]);
alert(JSON.stringify(arr)); // output: A, x, y, z, B, C
You can check it out in this jsFiddle: http://jsfiddle.net/luisperezphd/Wc8aS/
您可以在这个jsFiddle查看它:http://jsfiddle.net/luisperezphd/Wc8aS/
#3
7
This question is really old, but with ES6, there's a simpler way to do this using the spread operator:
这个问题很老了,但是有了ES6,有一种更简单的方法可以使用扩展运算符:
sourceArray.splice(index, 0, ...insertedArray)
If you're using uncompiled javascript in the browser, be sure to check if it's supported in your target browser at https://kangax.github.io/compat-table/es6/#test-spread_(...)_operator.
如果在浏览器中使用未编译的javascript,请确保在https://kangax.github.io/compat-table/es6/#test-spread_(…)_operator检查目标浏览器是否支持它。
Also, this may be slightly off topic, but if you don't want or need to modify the original array, but could use a new array instead, consider this approach:
此外,这可能有点偏离主题,但如果您不想或不需要修改原始数组,但可以使用新的数组,请考虑以下方法:
mergedArray = sourceArray.slice(0, index).concat(insertedArray, sourceArray.slice(index))
#4
6
You can also add such a function to the Array prototype, if you want something that is almost identical to the splice method. E.g.
如果您想要与splice方法几乎相同的东西,也可以向数组原型添加这样的函数。如。
Array.prototype.spliceArray = function(index, n, array) {
return Array.prototype.splice.apply(this, [index, n].concat(array));
}
Then usage would simply be:
那么用法就是:
var array = ["A","B","C","","E","F"];
array.splice(3,1,"D");
// array is ["A","B","C","D","E","F"]
array.spliceArray(3,3,["1","2","3"]);
// array is ["A","B","C","1","2","3"]
See it in action here: http://jsfiddle.net/TheMadDeveloper/knv2f8bb/1/
在这里可以看到:http://jsfiddle.net/TheMadDeveloper/knv2f8bb/1/
Some notes:
一些注意事项:
- The
splice
function modifies the array directly, but returns the an array of elements that were removed... not the spliced array. - splice函数直接修改数组,但是返回被删除的元素数组……不是拼接数组。
- While it's normally not recommended to extend core javascript classes, this is relatively benign with most standard frameworks.
- 虽然通常不建议扩展核心javascript类,但对于大多数标准框架来说,这是相对良性的。
- Extending
Array
won't work in cases where specialized array classes are used, such as an ImageData data Uint8ClampedArray. - 扩展数组在使用专用数组类(如ImageData数据Uint8ClampedArray)的情况下不能工作。
#5
1
The answers above that involve splice.apply and insert the array in a one liner will blow up the stack in a stack overflow for large array. See example here: http://jsfiddle.net/gkohen/u49ku99q/ You might have to slice and and push each item of the inserted and remaining part of the original array for it to work. See fiddle: http://jsfiddle.net/gkohen/g9abppgy/26/
上面的答案涉及到拼接。应用并插入数组到一个衬垫中,将在大数组的堆栈溢出中放大堆栈。请参见这里的示例:http://jsfiddle.net/gkohen/u49ku99q/您可能需要对插入的和原始数组的其余部分的每个项进行切片和推入,以便其工作。看到小提琴:http://jsfiddle.net/gkohen/g9abppgy/26/
Array.prototype.spliceArray = function(index, insertedArray) {
var postArray = this.splice(index);
inPlacePush(this, insertedArray);
inPlacePush(this, postArray);
function inPlacePush(targetArray, pushedArray) {
// Not using forEach for browser compatability
var pushedArrayLength = pushedArray.length;
for (var index = 0; index < pushedArrayLength; index++) {
targetArray.push(pushedArray[index]);
}
}
}
#6
0
I wanted to have a function which would take only part of the source array so I have mine slightly different based off CMS's answer
我想要一个函数只包含源数组的一部分,所以我的函数与CMS的答案稍有不同
function spliceArray(array, index, howmany, source, start, end) {
var arguments;
if( source !== undefined ){
arguments = source.slice(start, end);
arguments.splice(0,0, index, howmany);
} else{
arguments = [index, howmany];
}
return Array.prototype.splice.apply(array, arguments)
}
Array.prototype.spliceArray = function(index, howmany, source, start, end) {
return spliceArray(this, index, howmany, source, start, end);
}
You can see it at: https://jsfiddle.net/matthewvukomanovic/nx858uz5/
您可以在:https://jsfiddle.net/matthewvukomanovic/nx858uz5/上看到它
#7
0
There are a lot of clever answers here, but the reason you use splice is so that it puts the elements into the current array without creating another. If you have to create an array to concat()
against so you can use apply()
then you're creating 2 additional trash arrays! Sorta defeats the whole purpose of writing esoteric Javascript. Besides if you don't care about that memory usage stuff (and you should) just dest = src1.concat(src2)
; it is infinitely more readable. So here's is my smallest number of lines while staying efficient answer.
这里有很多聪明的答案,但是使用splice的原因是它将元素放入当前数组中而不创建另一个。如果您必须创建一个用于concat()的数组,以便使用apply(),那么您将创建另外两个垃圾数组!Sorta挫败了编写深奥的Javascript的整个目的。此外,如果你不关心内存使用的东西(你应该),你只需要dest = src1.concat(src2);它的可读性强得多。这是我的最小行数,同时保持效率。
for( let item of src ) dest.push( item );
Or if you'd like to polyfill it and have a little better browser support back:
或者如果你想多填充它并有更好的浏览器支持:
src.forEach( function( x ) { dest.push(x); });
I'm sure the first is more performant (it's a word ;), but not supported in all browsers out there in the wild.
我确信第一个是性能更好的(它是一个词;),但并不是所有的浏览器都支持。
#1
120
You can use apply to avoid eval:
您可以使用apply来避免eval:
var args = [start, number].concat(newItemsArray);
Array.prototype.splice.apply(theArray, args);
The apply function is used to call another function, with a given context and arguments, provided as an array, for example:
apply函数用于调用另一个函数,该函数具有给定的上下文和参数(如数组):
If we call:
如果我们所说的:
var nums = [1,2,3,4];
Math.min.apply(Math, nums);
The apply function will execute:
应用函数将执行:
Math.min(1,2,3,4);
#2
26
UPDATE: ES6 version
更新:ES6版本
If your coding in ES6 you can use the "spread operator" (...)
如果您在ES6中编写代码,您可以使用“扩展操作符”(…)
array.splice(index, 0, ...arrayToInsert);
To learn more about the spread operator see mozilla documentation.
要了解有关扩展操作符的更多信息,请参阅mozilla文档。
The 'old' ES5 way
“老”ES5的方式
If you wrap the top answer into a function you get this:
如果你把上面的答案打包成一个函数,你会得到:
function insertArrayAt(array, index, arrayToInsert) {
Array.prototype.splice.apply(array, [index, 0].concat(arrayToInsert));
}
You would use it like this:
你可以这样使用它:
var arr = ["A", "B", "C"];
insertArrayAt(arr, 1, ["x", "y", "z"]);
alert(JSON.stringify(arr)); // output: A, x, y, z, B, C
You can check it out in this jsFiddle: http://jsfiddle.net/luisperezphd/Wc8aS/
您可以在这个jsFiddle查看它:http://jsfiddle.net/luisperezphd/Wc8aS/
#3
7
This question is really old, but with ES6, there's a simpler way to do this using the spread operator:
这个问题很老了,但是有了ES6,有一种更简单的方法可以使用扩展运算符:
sourceArray.splice(index, 0, ...insertedArray)
If you're using uncompiled javascript in the browser, be sure to check if it's supported in your target browser at https://kangax.github.io/compat-table/es6/#test-spread_(...)_operator.
如果在浏览器中使用未编译的javascript,请确保在https://kangax.github.io/compat-table/es6/#test-spread_(…)_operator检查目标浏览器是否支持它。
Also, this may be slightly off topic, but if you don't want or need to modify the original array, but could use a new array instead, consider this approach:
此外,这可能有点偏离主题,但如果您不想或不需要修改原始数组,但可以使用新的数组,请考虑以下方法:
mergedArray = sourceArray.slice(0, index).concat(insertedArray, sourceArray.slice(index))
#4
6
You can also add such a function to the Array prototype, if you want something that is almost identical to the splice method. E.g.
如果您想要与splice方法几乎相同的东西,也可以向数组原型添加这样的函数。如。
Array.prototype.spliceArray = function(index, n, array) {
return Array.prototype.splice.apply(this, [index, n].concat(array));
}
Then usage would simply be:
那么用法就是:
var array = ["A","B","C","","E","F"];
array.splice(3,1,"D");
// array is ["A","B","C","D","E","F"]
array.spliceArray(3,3,["1","2","3"]);
// array is ["A","B","C","1","2","3"]
See it in action here: http://jsfiddle.net/TheMadDeveloper/knv2f8bb/1/
在这里可以看到:http://jsfiddle.net/TheMadDeveloper/knv2f8bb/1/
Some notes:
一些注意事项:
- The
splice
function modifies the array directly, but returns the an array of elements that were removed... not the spliced array. - splice函数直接修改数组,但是返回被删除的元素数组……不是拼接数组。
- While it's normally not recommended to extend core javascript classes, this is relatively benign with most standard frameworks.
- 虽然通常不建议扩展核心javascript类,但对于大多数标准框架来说,这是相对良性的。
- Extending
Array
won't work in cases where specialized array classes are used, such as an ImageData data Uint8ClampedArray. - 扩展数组在使用专用数组类(如ImageData数据Uint8ClampedArray)的情况下不能工作。
#5
1
The answers above that involve splice.apply and insert the array in a one liner will blow up the stack in a stack overflow for large array. See example here: http://jsfiddle.net/gkohen/u49ku99q/ You might have to slice and and push each item of the inserted and remaining part of the original array for it to work. See fiddle: http://jsfiddle.net/gkohen/g9abppgy/26/
上面的答案涉及到拼接。应用并插入数组到一个衬垫中,将在大数组的堆栈溢出中放大堆栈。请参见这里的示例:http://jsfiddle.net/gkohen/u49ku99q/您可能需要对插入的和原始数组的其余部分的每个项进行切片和推入,以便其工作。看到小提琴:http://jsfiddle.net/gkohen/g9abppgy/26/
Array.prototype.spliceArray = function(index, insertedArray) {
var postArray = this.splice(index);
inPlacePush(this, insertedArray);
inPlacePush(this, postArray);
function inPlacePush(targetArray, pushedArray) {
// Not using forEach for browser compatability
var pushedArrayLength = pushedArray.length;
for (var index = 0; index < pushedArrayLength; index++) {
targetArray.push(pushedArray[index]);
}
}
}
#6
0
I wanted to have a function which would take only part of the source array so I have mine slightly different based off CMS's answer
我想要一个函数只包含源数组的一部分,所以我的函数与CMS的答案稍有不同
function spliceArray(array, index, howmany, source, start, end) {
var arguments;
if( source !== undefined ){
arguments = source.slice(start, end);
arguments.splice(0,0, index, howmany);
} else{
arguments = [index, howmany];
}
return Array.prototype.splice.apply(array, arguments)
}
Array.prototype.spliceArray = function(index, howmany, source, start, end) {
return spliceArray(this, index, howmany, source, start, end);
}
You can see it at: https://jsfiddle.net/matthewvukomanovic/nx858uz5/
您可以在:https://jsfiddle.net/matthewvukomanovic/nx858uz5/上看到它
#7
0
There are a lot of clever answers here, but the reason you use splice is so that it puts the elements into the current array without creating another. If you have to create an array to concat()
against so you can use apply()
then you're creating 2 additional trash arrays! Sorta defeats the whole purpose of writing esoteric Javascript. Besides if you don't care about that memory usage stuff (and you should) just dest = src1.concat(src2)
; it is infinitely more readable. So here's is my smallest number of lines while staying efficient answer.
这里有很多聪明的答案,但是使用splice的原因是它将元素放入当前数组中而不创建另一个。如果您必须创建一个用于concat()的数组,以便使用apply(),那么您将创建另外两个垃圾数组!Sorta挫败了编写深奥的Javascript的整个目的。此外,如果你不关心内存使用的东西(你应该),你只需要dest = src1.concat(src2);它的可读性强得多。这是我的最小行数,同时保持效率。
for( let item of src ) dest.push( item );
Or if you'd like to polyfill it and have a little better browser support back:
或者如果你想多填充它并有更好的浏览器支持:
src.forEach( function( x ) { dest.push(x); });
I'm sure the first is more performant (it's a word ;), but not supported in all browsers out there in the wild.
我确信第一个是性能更好的(它是一个词;),但并不是所有的浏览器都支持。