在另一个数组中插入数组的更有效方法是什么。
a1 = [1,2,3,4,5];
a2 = [21,22];
newArray - a1.insertAt(2,a2) -> [1,2, 21,22, 3,4,5];
如果a2数组很大,从性能的角度来看,使用splice迭代a2看起来有点糟糕。
感谢。
答案 0 :(得分:149)
您可以使用splice
结合某些apply
技巧:
a1 = [1,2,3,4,5];
a2 = [21,22];
a1.splice.apply(a1, [2, 0].concat(a2));
console.log(a1); // [1, 2, 21, 22, 3, 4, 5];
在ES2015 +中,您可以使用扩展运算符来使其更好一些
a1.splice(2, 0, ...a2);
答案 1 :(得分:13)
一开始就错了。应该使用concat()
代替。
var a1 = [1,2,3,4,5],
a2 = [21,22],
startIndex = 0,
insertionIndex = 2,
result;
result = a1.slice(startIndex, insertionIndex).concat(a2).concat(a1.slice(insertionIndex));
示例: http://jsfiddle.net/f3cae/1/
此表达式使用slice(0, 2)
[docs]返回a1
的前两个元素(其中0
是起始索引,2
是元素deleteCount,尽管{{1没有改变)。
中级结果:a1
然后使用concat(a2)
[docs]将[1,2]
附加到a2
的末尾。
中级结果:[1,2]
。
接下来,[1,2,21,22]
在此表达式尾部的尾随a1.slice(2)
内调用,相当于.concat()
。
对具有正整数参数的[1,2,21,22].concat(a1.slice(2))
的调用将返回第二个元素之后的所有元素,按自然数计算(因为,有五个元素,因此slice(2)
将从[3,4,5]
)。另一种说法是,单数整数索引参数告诉a1
数组中的哪个位置开始返回元素(索引2是第三个元素)。
中级结果:a1.slice()
最后,第二个[1,2,21,22].concat([3,4,5])
将.concat()
添加到[3,4,5]
的末尾。
结果:[1,2,21,22]
改变[1,2,21,22,3,4,5]
可能很诱人,但可以使用原型继承扩展Array对象并将所述新对象注入到项目中。
然而,对于那些生活在边缘的人来说......
示例: http://jsfiddle.net/f3cae/2/
Array.prototype
答案 2 :(得分:9)
如果使用ES2015或更高版本,现在可以执行此操作:
var a1 = [1,2,3,4,5];
var a2 = [21,22];
a1.splice(2, 0, ...a2);
console.log(a1) // => [1,2,21,22,3,4,5]
有关spread(...)运算符https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
的文档,请参阅此处答案 3 :(得分:2)
我希望找到一种方法,使用splice()
执行此操作,而不是迭代:http://jsfiddle.net/jfriend00/W9n27/。
a1 = [1,2,3,4,5];
a2 = [21,22];
a2.unshift(2, 0); // put first two params to splice onto front of array
a1.splice.apply(a1, a2); // pass array as arguments parameter to splice
console.log(a1); // [1, 2, 21, 22, 3, 4, 5];
通用功能形式:
function arrayInsertAt(destArray, pos, arrayToInsert) {
var args = [];
args.push(pos); // where to insert
args.push(0); // nothing to remove
args = args.concat(arrayToInsert); // add on array to insert
destArray.splice.apply(destArray, args); // splice it in
}
答案 4 :(得分:2)
spread运算符允许在需要多个参数(用于函数调用)或多个元素(用于数组文字)的位置扩展表达式。
a2 = [21,22];
a1 = [1,2,...a2,3,4,5];//...a2 is use of spread operator
console.log(a1);
答案 5 :(得分:0)
var a1 = [1,2,3,4,5];
var a2 = [21,22];
function injectAt(d, a1, a2) {
for(var i=a1.length-1; i>=d; i--) {
a1[i + a2.length] = a1[i];
}
for(var i=0; i<a2.length; i++) {
a1[i+d] = a2[i];
}
}
injectAt(2, a1, a2);
alert(a1);
答案 6 :(得分:0)
这是我的版本,没有特别的技巧:
function insert_array(original_array, new_values, insert_index) {
for (var i=0; i<new_values.length; i++) {
original_array.splice((insert_index + i), 0, new_values[i]);
}
return original_array;
}
答案 7 :(得分:0)
如果要在不创建新数组的情况下将另一个数组插入数组,最简单的方法是使用push
或unshift
apply
例如:
a1 = [1,2,3,4,5];
a2 = [21,22];
// Insert a1 at beginning of a2
a2.unshift.apply(a2,a1);
// Insert a1 at end of a2
a2.push.apply(a2,a1);
这是有效的,因为push
和unshift
都采用了可变数量的参数。
奖金,您可以轻松选择从哪个端点附加阵列!
答案 8 :(得分:0)
如另一个帖子所述,上面的答案不适用于非常大的数组(200K元素)。请参阅此处涉及拼接和手动推送的备用答案:https://stackoverflow.com/a/41465578/1038326
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]);
}
}
}
答案 9 :(得分:0)
这里有一些真正有创意的答案。对于那些刚开始使用数组的人来说,这是一个简单的解决方案。如果需要,可以使其一直运行到兼容ECMAScript 3的浏览器。
开始使用之前,请先了解一些有关拼接的知识。
Mozilla Developer Network: Array.prototype.splice()
首先,了解.splice()
的两种重要形式。
let a1 = [1,2,3,4],
a2 = [1,2];
方法1)从所需的索引处删除x(deleteCount)个元素。
let startIndex = 0,
deleteCount = 2;
a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4]
方法2)从所需的起始索引到数组的结尾删除元素。
a1.splice(2); // returns [3,4], a1 would be [1,2]
使用.splice()
,目标可能是通过使用以上两种形式之一将a1
分为头尾阵列。
使用方法#1,返回值将成为头部,a1
将成为尾部。
let head = a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4]
现在,一举将头,身体(a2
)和尾巴连接起来
[].concat(head, a2, a1);
因此,此解决方案比到目前为止提供的任何其他解决方案都更像现实世界。这不是您乐高积木会做的吗? ;-)这是一个使用方法2完成的功能。
/**
*@param target Array The array to be split up into a head and tail.
*@param body Array The array to be inserted between the head and tail.
*@param startIndex Integer Where to split the target array.
*/
function insertArray(target, body, startIndex)
{
let tail = target.splice(startIndex); // target is now [1,2] and the head
return [].concat(target, body, tail);
}
let newArray = insertArray([1, 2, 3, 4], ["a", "b"], 2); // [1, 2, "a", "b", 3, 4]
更短:
/**
*@param target Array The array to be split up into a head and tail.
*@param body Array The array to be inserted between the head and tail.
*@param startIndex Integer Where to split the target array.
*/
function insertArray(target, body, startIndex)
{
return [].concat(target, body, target.splice(startIndex));
}
更安全:
/**
*@param target Array The array to be split up into a head and tail.
*@param body Array The array to be inserted between the head and tail.
*@param startIndex Integer Where to split the target array.
*@throws Error The value for startIndex must fall between the first and last index, exclusive.
*/
function insertArray(target, body, startIndex)
{
const ARRAY_START = 0,
ARRAY_END = target.length - 1,
ARRAY_NEG_END = -1,
START_INDEX_MAGNITUDE = Math.abs(startIndex);
if (startIndex === ARRAY_START) {
throw new Error("The value for startIndex cannot be zero (0).");
}
if (startIndex === ARRAY_END || startIndex === ARRAY_NEG_END) {
throw new Error("The startIndex cannot be equal to the last index in target, or -1.");
}
if (START_INDEX_MAGNITUDE >= ARRAY_END) {
throw new Error("The absolute value of startIndex must be less than the last index.");
}
return [].concat(target, body, target.splice(startIndex));
}
此解决方案的优点包括:
1)一个简单的前提主导了解决方案-填充一个空数组。
2)头,身体和尾部的命名法很自然。
3)不能双重呼叫.slice()
。完全没有切片。
4)否.apply()
。完全没有必要。
5)避免方法链接。
6)只需使用var
而不是let
或const
,即可在ECMAScript 3和5中工作。
** 7)确保将头和尾巴拍打到身体上,这与提出的许多其他解决方案不同。如果要在边界之前或之后添加数组,则至少应使用.concat()
!!!!
请注意:使用扩散人工监督者...
使所有这些工作变得更加容易。