[javascript] 새 배열을 만들지 않고 기존 JavaScript 배열을 다른 배열로 확장하는 방법

기존 JavaScript 배열을 다른 배열로 확장하는 방법, 즉 Python의 extend메소드 를 에뮬레이트하는 방법이없는 것 같습니다 .

다음을 달성하고 싶습니다.

>>> a = [1, 2]
[1, 2]
>>> b = [3, 4, 5]
[3, 4, 5]
>>> SOMETHING HERE
>>> a
[1, 2, 3, 4, 5]

나는 거기에 알 a.concat(b)방법이 있지만, 단순히 첫 번째 확장 대신 새로운 배열을 작성합니다. a보다 큰 경우 b(즉, 복사하지 않는 a) 보다 효율적으로 작동하는 알고리즘을 원합니다 .

참고 : 이것은 배열에 무언가를 추가하는 방법과 중복되지 않습니다 . 여기서 목표는 한 배열의 전체 내용을 다른 배열에 추가하고 “정확한”확장 배열의 모든 요소를 ​​복사하지 않고 수행하는 것입니다.



답변

.push메소드는 여러 인수를 취할 수 있습니다. spread 연산자 를 사용하여 두 번째 배열의 모든 요소를 ​​인수로 전달할 수 있습니다 .push.

>>> a.push(...b)

브라우저가 ECMAScript 6을 지원하지 않으면 .apply대신 사용할 수 있습니다 .

>>> a.push.apply(a, b)

또는 더 명확하다고 생각되면 :

>>> Array.prototype.push.apply(a,b)

배열 b이 너무 길면 이러한 모든 솔루션이 스택 오버플로 오류와 함께 실패 합니다 (브라우저에 따라 약 100,000 개의 요소에서 문제가 시작됨).
그것이 b충분히 짧은 것을 보장 할 수 없다면 , 다른 답변에서 설명 된 표준 루프 기반 기술을 사용해야합니다.


답변

업데이트 2018 : 더 나은 대답은 내 새로운 하나입니다 : a.push(...b). 그것은 실제로 질문에 대답하지 않았으므로 더 이상 이것을 찬성하지 마십시오.


단순히 “JavaScript array extend”를 검색하여 여기에 온 사람들은을 매우 잘 사용할 수 있습니다 Array.concat.

var a = [1, 2, 3];
a = a.concat([5, 4, 3]);

스레드 스타터가 원하지 않았으므로 Concat은 새 배열의 복사본을 반환합니다. 그러나 당신은 신경 쓰지 않을 것입니다 (확실히 대부분의 종류의 용도에는 이것이 좋을 것입니다).


스프레드 연산자의 형태로 이것을위한 멋진 ECMAScript 6 설탕도 있습니다 :

const a = [1, 2, 3];
const b = [...a, 5, 4, 3];

(또한 복사합니다.)


답변

루프 기반 기술을 사용해야합니다. 이 페이지에서 사용을 기반으로하는 다른 답변 .apply은 큰 배열에서 실패 할 수 있습니다.

상당히 간결한 루프 기반 구현은 다음과 같습니다.

Array.prototype.extend = function (other_array) {
    /* You should include a test to check whether other_array really is an array */
    other_array.forEach(function(v) {this.push(v)}, this);
}

그런 다음 다음을 수행 할 수 있습니다.

var a = [1,2,3];
var b = [5,4,3];
a.extend(b);

.apply우리가 추가하는 배열이 클 때 DzinX의 답변 (push.apply 사용) 및 기타 기반 메소드가 실패합니다 (테스트 결과 Chrome의 경우 약 150,000 항목, Firefox의 경우 500,000 항목). 이 jsperf 에서이 오류가 발생하는 것을 볼 수 있습니다 .

두 번째 인수로 큰 배열을 사용하여 ‘Function.prototype.apply’를 호출하면 호출 스택 크기가 초과되어 오류가 발생합니다. MDN은 Function.prototype.apply를 사용하여 호출 스택 크기를 초과 할 위험에 대해 설명합니다. “적용 및 내장 함수”섹션을 참조하십시오.

이 페이지의 다른 답변과 속도를 비교하려면 이 jsperf를 확인하십시오 ( EttererOfCode 덕분에). 루프 기반 구현은을 사용하는 속도와 비슷 Array.push.apply하지만 약간 느립니다 Array.slice.apply.

흥미롭게도, 추가하려는 배열이 희소 인 경우 forEach위 의 기본 방법은 희소성을 활용하고 .apply기본 방법 보다 성능이 우수합니다 . 이것을 직접 테스트하려면 이 jsperf를 확인 하십시오.

그건 그렇고, forEach 구현을 다음과 같이 단축하기 위해 (나처럼) 유혹을받지 마십시오.

Array.prototype.extend = function (array) {
    array.forEach(this.push, this);
}

이것은 쓰레기 결과를 생성하기 때문에! 왜? 때문에 Array.prototype.forEach이 호출하는 함수에 세 가지 인수를 제공 – 다음은 다음과 같습니다 (element_value, element_index, 오기 source_array). forEach“forEach (this.push, this)”를 사용하면이 모든 것들이 반복 될 때마다 첫 번째 배열로 푸시됩니다 !


답변

요즘 가장 우아하다고 생각합니다.

arr1.push(...arr2);

확산 연산자에 대한 MDN 문서 ES2015 (ES6)이 좋은 달콤한 방법을 언급한다 :

더 나은 푸시

예 : push는 배열을 기존 배열의 끝으로 밀어 넣는 데 자주 사용됩니다. ES5에서는 종종 다음과 같이 수행됩니다.

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// Append all items from arr2 onto arr1
Array.prototype.push.apply(arr1, arr2);

스프레드가있는 ES6에서는 다음과 같이됩니다.

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);

참고 수행 arr2거대 호출 스택이 jcdude의 대답에 따라, 오버 플로우 때문에, (000 (100)에 대한 항목에서 보관) 할 수 있습니다.


답변

apply()JavaScript를 사용하는 이유를 이해하는 데 도움이되는 JavaScript에 대한 몇 마디 :

apply()메소드는 주어진 this값을 가진 함수와 배열로 제공된 인수를 호출합니다 .

푸시는 항목 목록 이 배열에 추가 될 것으로 예상합니다 . apply()방법은 그러나, 배열로의 함수 호출에 대한 예상 인자 걸린다. 이를 통해 push내장 push()메소드를 사용하여 한 배열의 요소를 다른 배열로 쉽게 만들 수 있습니다 .

이 배열이 있다고 상상해보십시오.

var a = [1, 2, 3, 4];
var b = [5, 6, 7];

그리고 간단히 이렇게하십시오 :

Array.prototype.push.apply(a, b);

결과는 다음과 같습니다.

a = [1, 2, 3, 4, 5, 6, 7];

다음과 같이 스프레드 연산자 ( ” ...“)를 사용하여 ES6에서 동일한 작업을 수행 할 수 있습니다 .

a.push(...b); //a = [1, 2, 3, 4, 5, 6, 7]; 

현재 모든 브라우저에서 짧고 우수하지만 완전히 지원되지는 않습니다.

당신이 원하는 또한 경우 이동 배열에서 모든 b대상을 a비우는 b과정에서, 당신은이 작업을 수행 할 수 있습니다 :

while(b.length) {
  a.push(b.shift());
} 

결과는 다음과 같습니다.

a = [1, 2, 3, 4, 5, 6, 7];
b = [];


답변

jQuery를 사용하려면 $ .merge ()가 있습니다.

예:

a = [1, 2];
b = [3, 4, 5];
$.merge(a,b);

결과 : a = [1, 2, 3, 4, 5]


답변

a.push.apply(a, b)위에서 설명한 방법을 좋아하며 원하는 경우 언제든지 다음과 같은 라이브러리 함수를 만들 수 있습니다.

Array.prototype.append = function(array)
{
    this.push.apply(this, array)
}

이렇게 사용하세요

a = [1,2]
b = [3,4]

a.append(b)