[javascript] Javascript-다른 배열 안에 배열 삽입

다른 배열 안에 배열을 삽입하는 더 효율적인 방법은 무엇입니까?

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

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

splice를 사용하여 a2를 반복하는 것은 a2 배열이 큰 경우 성능 관점에서 약간 끔찍하게 보입니다.

감사.



답변

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


답변

이제 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시작 인덱스이고 변경되지는 않지만 2deleteCount 요소 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)양의 정수 인수를 갖는에 대한 호출 은 자연수로 계산하여 두 번째 요소 이후의 모든 요소를 ​​반환합니다 (에서와 같이 5 개의 요소 [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 );


답변

확산 연산자는 식 또는 (배열 리터럴) 여러 요소 (함수 호출에 대한) 다수의 인수가 예상되는 위치에 확장 될 수있다.

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


답변

여기에이 질문에 대한 진정으로 창의적인 답변이 있습니다. 다음은 배열로 시작하는 사람들을위한 간단한 솔루션입니다. 원하는 경우 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대신 사용하여 ECMAScript 3 및 5에서 작동 합니다.letconst

** 7) 제시된 다른 많은 솔루션과 달리 머리와 꼬리가 몸을 때릴 수 있도록합니다. 경계 앞이나 뒤에 배열을 추가하는 경우 적어도 .concat()!!!! 를 사용해야합니다.

참고 : Spread opearator를 ...사용하면이 모든 작업을 훨씬 쉽게 수행 할 수 있습니다.


답변

나는 이것을 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
}


답변

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