Javascript - 在另一个数组中插入一个数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7032550/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 00:20:25  来源:igfitidea点击:

Javascript - insert an array inside another array

javascriptarraysperformance

提问by ic3

What is the more efficient way to insert an array inside another array.

在另一个数组中插入数组的更有效方法是什么。

a1 = [1,2,3,4,5];
a2 = [21,22];

newArray - a1.insertAt(2,a2) -> [1,2, 21,22, 3,4,5];

Iterating a2 using splice looks a bit awfull from a performance point of view if a2 array is large.

如果 a2 数组很大,从性能的角度来看,使用 splice 迭代 a2 看起来有点可怕。

Thanks.

谢谢。

回答by nickf

You can use splicecombined with some applytrickery:

您可以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];

In ES2015+, you could use the spread operator instead to make this a bit nicer

在 ES2015+ 中,您可以使用扩展运算符来使它更好一点

a1.splice(2, 0, ...a2);

回答by Elmer

You can now do this if using ES2015 or later:

如果使用 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]

Refer to this for documenation on the spread (...) operator https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator

有关传播 (...) 运算符的文档,请参阅此https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator

回答by user113716

Had it wrong at first. Should have used concat()instead.

一开始就错了。应该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));

Example:http://jsfiddle.net/f3cae/1/

示例:http : //jsfiddle.net/f3cae/1/

This expression uses slice(0, 2)[docs]to return the first two elements of a1(where 0is the starting index, and 2is the element deleteCount, though a1is not altered).

此表达式使用slice(0, 2)[docs]返回a1(where0是起始索引,2是元素 deleteCount,a1但未更改)的前两个元素。

Intermediate result: [1,2]

中间结果[1,2]

It then uses concat(a2)[docs]to append a2to the end of the [1,2].

然后它使用concat(a2)[docs]附加a2[1,2].

Intermediate result:[1,2,21,22].

中间结果[1,2,21,22]

Next, a1.slice(2)is called within a trailing .concat()at the tail end of this expression, which amounts to [1,2,21,22].concat(a1.slice(2)).

Next,在此表达式a1.slice(2)尾端的尾随内调用.concat(),相当于[1,2,21,22].concat(a1.slice(2))

A call to slice(2), having a positive integer argument, will return all elements after the 2nd element, counting by natural numbers (as in, there are five elements, so [3,4,5]will be returned from a1). Another way to say this is that the singular integer index argument tells a1.slice()at which position in the array to start returning elements from (index 2 is the third element).

调用slice(2)具有正整数参数的 ,将返回第二个元素之后的所有元素,按自然数计数(因为有五个元素,因此[3,4,5]将从 返回a1)。另一种说法是奇异整数索引参数告诉a1.slice()从数组中的哪个位置开始返回元素(索引 2 是第三个元素)。

Intermediate result: [1,2,21,22].concat([3,4,5])

中间结果[1,2,21,22].concat([3,4,5])

Finally, the second .concat()adds [3,4,5]to the the end of [1,2,21,22].

最后,第二个.concat()添加[3,4,5][1,2,21,22].

Result: [1,2,21,22,3,4,5]

结果[1,2,21,22,3,4,5]

It may be tempting to alter Array.prototype, but one can simply extend the Array object using prototypal inheritance and inject said new object into your projects.

改变 可能很诱人Array.prototype,但可以简单地使用原型继承扩展 Array 对象并将所述新对象注入到您的项目中。

However, for those living on the edge ...

然而,对于那些生活在边缘的人......

Example:http://jsfiddle.net/f3cae/2/

示例: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 );

回答by Hikmat Sijapati

The spreadoperator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) are expected.

传播操作符允许表达式来在多个参数(对于函数调用)或多个元素(数组文本)预计的地方扩大。

a2 = [21,22];
a1 = [1,2,...a2,3,4,5];//...a2 is use of spread operator
console.log(a1);

回答by Anthony Rutledge

There are some truly creative answers to this question here. Here is a simple solution for those just starting out with arrays. It can be made to work all the way down to ECMAScript 3 compliant browsers, if desired.

对于这个问题,这里有一些真正有创意的答案。对于刚开始使用数组的人,这是一个简单的解决方案。如果需要,它可以一直工作到符合 ECMAScript 3 的浏览器。

Know something about splice before getting started.

在开始之前了解一些关于拼接的知识。

Mozilla Developer Network: Array.prototype.splice()

Mozilla 开发者网络:Array.prototype.splice()

First, understand two important forms of .splice().

首先,了解 的两种重要形式.splice()

let a1 = [1,2,3,4],
    a2 = [1,2];

Method 1) Remove x (deleteCount) elements, starting from a desired index.

方法 1) 从所需索引开始删除 x (deleteCount) 个元素。

let startIndex = 0, 
    deleteCount = 2;

a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4]

Method 2) Remove elements after a desired start index to the end of the array.

方法 2) 从所需的起始索引到数组末尾删除元素。

a1.splice(2); // returns [3,4], a1 would be [1,2]

Using .splice(), a goal could be to split a1into head and tail arrays by using one of the two forms above.

使用.splice(),目标可以是a1通过使用上述两种形式之一拆分为头和尾数组。

Using method #1, the return value would become the head, and a1the tail.

使用方法#1,返回值将成为头部和a1尾部。

let head = a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4]

Now, in one fell swoop, concatenate the head, body (a2), and tail

现在,一举将头部、身体 ( a2) 和尾部连接起来

[].concat(head, a2, a1);

Thus, this solution is more like the real world than any other presented thus far. Is this not what you would do with Legos? ;-) Here is a function, done using method #2.

因此,这个解决方案比迄今为止提出的任何其他解决方案更像现实世界。这不是你会用乐高积木做的吗?;-) 这是一个函数,使用方法#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]

Shorter:

更短:

/**
*@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));
}

Safer:

更安全:

/**
*@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));
}

The advantages of this solution include:

该解决方案的优点包括:

1) A simple premise dominates the solution--fill an empty array.

1)一个简单的前提支配了解决方案——填充一个空数组。

2) Head, body, and tail nomenclature feels natural.

2) 头部、身体和尾部的命名法感觉很自然。

3) No double call to .slice(). No slicing at all.

3) 没有对.slice(). 根本没有切片。

4) No .apply(). Highly unnecessary.

4) 没有.apply()。非常没有必要。

5) Method chaining is avoided.

5) 避免了方法链接。

6) Works in ECMAScript 3 and 5 simply by using varinstead of letor const.

6) 只需使用var代替let或即可在 ECMAScript 3 和 5中工作const

**7) Ensures that there will be a head and tail to slap on to the body, unlike many other solutions presented. If you are adding an array before, or after, the bounds, you should at least be using .concat()!!!!

**7) 确保有一个头部和尾部可以拍打身体,这与许多其他解决方案不同。如果您在边界之前或之后添加数组,您至少应该使用.concat()!!!!

Note: Use of the spread opearator ...makes all of this much easier to accomplish.

注意:使用扩展运算符...使所有这些更容易完成。

回答by jfriend00

I wanted to find a way to do this with splice()and no iterating: http://jsfiddle.net/jfriend00/W9n27/.

我想找到一种方法来做到这一点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];

In general purpose function form:

在通用函数形式中:

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
}

回答by Bhesh Gurung

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);

回答by arlomedia

Here's my version with no special tricks:

这是我的版本,没有特殊技巧:

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;
}

回答by RangerMauve

If you want to insert another array into an array without creating a new one, the easiest way is to use either pushor unshiftwith apply

如果你想插入另一个数组的数组,而无需创建一个新的,最简单的方法是要么使用pushunshiftapply

Eg:

例如:

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);

This works because both pushand unshifttake a variable number of arguments. A bonus, you can easily choose which end to attach the array from!

这工作,因为两者pushunshift带有可变数量的参数。一个奖励,您可以轻松选择从哪一端连接阵列!

回答by Gabriel Kohen

As mentioned in another thread,the answers above will not work in very large arrays (200K elements). See alternate answer here involving splice and manual push: https://stackoverflow.com/a/41465578/1038326

正如在另一个线程中提到的,上面的答案在非常大的数组(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]);
       }
    }
}