Program Tip

Javascript-다른 배열 안에 배열 삽입

programtip 2020. 10. 11. 11:16
반응형

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

처음에는 틀렸다. 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 );

이제 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를 참조하십시오.


나는 이것을 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 = [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) Works in ECMAScript 3 and 5 simply by using var instead of let or 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()!!!!

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


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

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

If you want to insert another array into an array without creating a new one, the easiest way is to use either push or unshift with apply

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 push and unshift take a variable number of arguments. A bonus, you can easily choose which end to attach the array from!


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

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

참고URL : https://stackoverflow.com/questions/7032550/javascript-insert-an-array-inside-another-array

반응형