在另一个数组中插入数组的更有效方法是什么。
a1 = [1,2,3,4,5];
a2 = [21,22];
newArray - a1.insertAt(2,a2) -> [1,2, 21,22, 3,4,5];
如果a2数组很大,从性能的角度来看,使用拼接来迭代a2看起来会有些糟。
谢谢。
Answers:
您可以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);
apply
将引发stackoverflow异常。jsfiddle.net/DcHCY也发生在jsPerf中,我相信FF和IE的阈值大约为500k
target.slice(0, insertIndex).concat(insertArr, target.slice(insertIndex));
jsperf.com/inserting-an-array-within-an-array
现在,如果使用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]
有关传播(...)运算符的文档,请参考此文档。https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
起初有错。应该使用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,尽管a1
未更改)。
中间结果:[1,2]
然后,它使用concat(a2)
[docs]附加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
)。另一种说法是,奇异整数索引参数告诉a1.slice()
数组从哪个位置开始返回元素(索引2是第三个元素)。
中间结果:[1,2,21,22].concat([3,4,5])
最后,第二个.concat()
添加[3,4,5]
到的末尾[1,2,21,22]
。
结果:[1,2,21,22,3,4,5]
进行更改可能很吸引人Array.prototype
,但是您可以使用原型继承简单地扩展Array对象,并将所述新对象注入您的项目中。
然而,对于那些生活在边缘的人...
示例: http ://jsfiddle.net/f3cae/2/
Array.prototype.injectArray = function( idx, arr ) {
return this.slice( 0, idx ).concat( arr ).concat( this.slice( idx ) );
};
var a1 = [1,2,3,4,5];
var a2 = [21,22];
var result = a1.injectArray( 2, a2 );
这里有一些真正有创意的答案。对于刚从数组开始的人来说,这是一个简单的解决方案。如果需要,可以使其一直运行到兼容ECMAScript 3的浏览器。
开始之前请先了解一些有关拼接的知识。
Mozilla开发人员网络: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
或即可在ECMAScript 3和5 中工作const
。
** 7)确保头和尾巴可以贴在身上,这与其他许多解决方案不同。如果要在边界之前或之后添加数组,则至少应使用.concat()
!!!!
注意:使用扩散式起皱...
器使所有这些操作变得更加容易。
我想找到一种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
}
a2
也会修改数组,这可能是非常不可取的。另外,Array.prototype
当您在a1
或上具有切片功能时,无需转到a2
。
apply()
方法中添加了对象。
Array.prototype.splice
vs a1.splice
:)
.concat
返回一个新数组,它不会修改现有数组,例如splice
。应该是args = args.concat(arrayToInsert);
这是我的版本,没有任何特殊技巧:
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;
}
.apply()
。
如果你想插入另一个数组的数组,而无需创建一个新的,最简单的方法是要么使用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
带有可变数量的参数。另外,您可以轻松地选择从哪个末端连接阵列!
a1.concat(a2)
否则a2.concat(a1)
我已经设计出比您建议的要容易的东西。但是,问题是在数组边界之间插入数组,而不是仅在数组的开头或结尾添加数组。;-)
就像在另一个线程中提到的那样,上面的答案不适用于非常大的数组(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]);
}
}
}