N 배열을 연결하는 가장 효율적인 방법은 무엇입니까?


답변:


323

두 개 이상의 어레이를 연결하는 경우 concat()편의성과 성능을 기대할 수있는 방법입니다.

var a = [1, 2], b = ["x", "y"], c = [true, false];
var d = a.concat(b, c);
console.log(d); // [1, 2, "x", "y", true, false];

두 개의 배열 만 연결 push하려면 배열에 추가 할 요소로 구성된 여러 인수 를 허용 한다는 사실을 사용하여 새 배열을 생성하지 않고 한 배열에서 다른 배열의 끝으로 요소를 추가 할 수 있습니다. 함께 slice()사용할 수도 concat()있지만 이렇게하면 성능 이점이없는 것 같습니다 .

var a = [1, 2], b = ["x", "y"];
a.push.apply(a, b);
console.log(a); // [1, 2, "x", "y"];

ECMAScript 2015 및 이후 버전에서는

a.push(...b)

그러나 대규모 배열 (10 만 멤버 이상)의 경우 배열을 요소 push( apply()ECMAScript 2015 스프레드 연산자를 사용 하거나 사용)에 전달하는 기술 이 실패 할 수 있습니다. 이러한 배열의 경우 루프를 사용하는 것이 더 좋습니다. 자세한 내용은 https://stackoverflow.com/a/17368101/96100 을 참조하십시오.


1
테스트에 오류가 있다고 생각합니다. a.concat(b)테스트 케이스가 불필요하게 배열의 사본을 a만든 다음 버리는 것 같습니다.
ninjagecko

1
@ninjagecko : 네 말이 맞아. 나는 그것을 업데이트했다 : jsperf.com/concatperftest/6 . 두 개의 기존 배열을 연결하는 새 배열을 만드는 특별한 경우에는 concat()일반적으로 더 빠릅니다. 기존 배열에 배열을 연결하는 경우 push()갈 길입니다. 답변을 업데이트했습니다.
Tim Down

16
push.apply 메소드를 사용하여 여러 개의 새로운 배열로 단일 배열을 확장하면 간단한 연결 호출보다 큰 성능 이점 (~ 100x)이 부여됩니다. v8 / node.js에서 짧은 정수 목록의 매우 긴 목록을 다루고 있습니다.
chbrown

1
더 간결한 방법은 a.push (... b);
dinvlad

1
@dinvlad : 맞지만 ES6 환경에서만. 내 답변에 메모를 추가했습니다.
Tim Down

158
[].concat.apply([], [array1, array2, ...])

편집 : 효율성 증명 : http://jsperf.com/multi-array-concat/7

edit2 : Tim Supinie는 주석에서 해석기가 호출 스택 크기를 초과 할 수 있다고 언급했습니다. 이것은 아마도 js 엔진에 달려 있지만 Chrome에서 적어도 "최대 호출 스택 크기 초과"를 얻었습니다. 테스트 사례 : [].concat.apply([], Array(300000).fill().map(_=>[1,2,3])). (현재 승인 된 답변을 사용하여 동일한 오류가 발생 했으므로 그러한 사용 사례를 예상하거나 다른 사람들을 위해 라이브러리를 구축 중이므로 어떤 솔루션을 선택하든 특별한 테스트가 필요할 수 있습니다.)


3
@ c69 : 적어도 Chrome에서 반복적으로 .push (#, #, ..., #)의 선택된 답변만큼 효율적으로 보입니다. jsperf.com/multi-array-concat Tim Down이 선택한 답변에도 오류가있을 수 있습니다. 이 링크는 질문에 따라 2 개가 아닌 여러 어레이를 결합한 성능을 비교합니다. 여러 가능한 길이가 테스트됩니다.
ninjagecko

IMO 이것은 n 개의 어레이를 "병합"하는 가장 효과적인 방법입니다
Eric Uldall

이 대답은 임의 길이의 배열 배열을 가지고 있고 모두 연결하기를 원하는 경우와 같이 N을 미리 알 수 없을 때 특히 유용합니다.
jfriend00

3
ES6 및 스프레드 연산자를 사용하면 훨씬 간단 해집니다. [] .concat (... [array1, array2, ...]) 글쎄, 두 번째 세 점은 약간 불행합니다. 처음 세 개는 스프레드 연산자 developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Eydrian

Eydrian : 스프레드 연산자는 매우 비효율적이기 때문에 개인적으로 피하려고 노력하지만, 구현이 미숙하거나 es6 사양의 의미가 약간 더 무거운 리프팅을 요구하기 때문에 아직 확실하지 않습니다. ). 이 특별한 경우에는 벤치 마크를 실행하지 않았습니다.
ninjagecko

34

ES2015 (ES6)를 사용하는 사람들

이제 스프레드 구문을 사용하여 배열을 연결할 수 있습니다.

const arr1 = [0, 1, 2],
      arr2 = [3, 4, 5];

const result1 = [...arr1, ...arr2]; // -> [0, 1, 2, 3, 4, 5]

// or...

const result2 = [...arr2, ...arr1]; // -> [3, 4, 5, 0, 1, 2]

이것이 얼마나 효율적입니까? 내가 테스트 한 결과 객체를 포함하는 배열의 경우 매우 느립니다. jsperf.com/array-concat-vs-array-push-vs-array-spread/1
hitautodestruct

28

concat()방법은 둘 이상의 배열을 결합하는 데 사용됩니다. 기존 배열은 변경하지 않고 결합 된 배열의 사본 만 반환합니다.

array1 = array1.concat(array2, array3, array4, ..., arrayN);

1
때로는 원래 배열을 수정하지 않는 JavaScript가 싫어. 🙄
Vincent Hoch-Drei

@ VincentHoch-Drei concat는 원래 배열을 변경하지 않고 새 배열을 만드는 데 특히 사용됩니다. 를 업데이트 array1하려면을 사용해야합니다.array1.push(...array2, ...array3, ...array4)
adiga

24

Array.prototype.concat.apply를 사용하여 여러 배열의 연결을 처리하십시오.

var resultArray = Array.prototype.concat.apply([], arrayOfArraysToConcat);

예:

var a1 = [1, 2, 3],
    a2 = [4, 5],
    a3 = [6, 7, 8, 9];
Array.prototype.concat.apply([], [a1, a2, a3]); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

1
난이게 좋아! 가변 수의 배열로 쉽게 작동하여 연결할 수 있습니다. +1
Joel

14

맵 / 필터 / 정렬 등을 통해 결과를 파이핑하는 동안 배열의 배열을 연결하려는 경우 사용할 수 있습니다 reduce

let sorted_nums = ['1,3', '4,2']
  .map(item => item.split(','))   // [['1', '3'], ['4', '2']]
  .reduce((a, b) => a.concat(b))  // ['1', '3', '4', '2']
  .sort()                         // ['1', '2', '3', '4']

14

여러 어레이 및 ES6의 경우

Array.prototype.concat(...arr);

예를 들면 다음과 같습니다.

const arr = [[1, 2, 3], [4, 5, 6], [7, 8 ,9]];
const newArr = Array.prototype.concat(...arr);
// output: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

1
또한를 사용하여 중복 요소를 제거 할 수 있습니다 newArr = Array.from(new Set(newArr));.
다리우스 M.

왜 typescript에서 이것이 any[]됩니까? 타이핑이 있습니다-이상합니다.
Simon_Weaver 4

이것은 더 큰 어레이 볼륨에서 실제로 매우 비효율적입니다. jsperf.com/flatten-array-203948 [].concat.apply([], ...arr) 은 대용량에서 훨씬 더 나은 성능을 제공합니다.
colemars

7

이제를 사용하여 여러 배열을 결합 할 수 있습니다 ES6 Spread. concat()배열을 연결 하는 데 사용 하는 대신 확산 구문을 사용하여 여러 배열을 하나의 평평한 배열로 결합하십시오. 예 :

var a = [1,2];
var b = [3,4];
var c = [5,6,7];
var d = [...a, ...b, ...c];
// resulting array will be like d = [1,2,3,4,5,6,7]

5

이렇게 해결했습니다.

let arr = [[1, 2], [3, 4], [5, 6]];
 console.log([].concat(...arr));

완벽한 솔루션.
nehem

4

jsperf.com 사이트를 사용 하여 성능을 비교할 수 있습니다 . concat에 대한 링크는 다음과 같습니다. 입니다.

다음 사이에 비교를 추가했습니다.

var c = a.concat(b);

과:

var c = [];
for (i = 0; i < a.length; i++) {
    c.push(a[i]);
}
for (j = 0; j < b.length; j++) {
    c.push(b[j]);
}

두 번째는 크롬에서 거의 10 배 느립니다.


그러나 Chrome을 제외한 모든 브라우저에서 push.apply()보다 더 빠른 것 같습니다 concat(). 내 대답을 참조하십시오.
팀 다운


3

여러 배열을 연결할 수있는 함수는 다음과 같습니다.

function concatNarrays(args) {
    args = Array.prototype.slice.call(arguments);
    var newArr = args.reduce( function(prev, next) {
       return prev.concat(next) ;
    });

    return newArr;
}

예 -

console.log(concatNarrays([1, 2, 3], [5, 2, 1, 4], [2,8,9]));

출력합니다

[1,2,3,5,2,1,4,2,8,9]

2

배열 배열이 있고 요소를 단일 배열로 연결하려면 다음 코드를 시도하십시오 (ES2015 필요).

let arrOfArr = [[1,2,3,4],[5,6,7,8]];
let newArr = [];
for (let arr of arrOfArr) {
    newArr.push(...arr);
}

console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];

또는 함수형 프로그래밍을하고 있다면

let arrOfArr = [[1,2,3,4],[5,6,7,8]];
let newArr = arrOfArr.reduce((result,current)=>{
    result.push(...current);
    return result;
});

console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];

또는 스프레드 연산자없이 ES5 구문을 사용하면 더 좋습니다.

var arrOfArr = [[1,2,3,4],[5,6,7,8]];
var newArr = arrOfArr.reduce((result,current)=>{
    return result.concat(current);
});
console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];

이 방법은 번호를 모르면 편리합니다. 코드 시간에 배열.


2

ES6로 줄이십시오.

new Set([].concat(...Array));

이것은 여러 배열을 연결 하고 독특하게 만듭니다 .

코드 펜 데모


그것은하지만 중복을 제거합니다 .. 중복 배열을 제거하지 않으려면 어떻게해야합니까?
Krunal Shah

new Set()중복 된 항목을 제거합니다. 그냥 제거하십시오. [].concat(...Array)
ronaldtgi

new Set ([]. concat (... Array));를 사용하고 싶습니다. 그러나 나는 또한 단일 표현에서 그것과 함께 중복을 제거하고 싶습니다. 가능합니까?
Krunal Shah

2

푸시로 어레이 병합 :

const array1 = [2, 7, 4];
const array2 = [3, 5,9];
array1.push(...array2);
console.log(array1)

사용 CONCAT확산 운영자 :

const array1 = [1,2];
const array2 = [3,4];

// Method 1: Concat 
const combined1 = [].concat(array1, array2);

// Method 2: Spread
const combined2 = [...array1, ...array2];

console.log(combined1);
console.log(combined2);


1

여기서 'n'은 몇 개의 배열, 아마도 배열의 배열입니다. . .

var answer = _.reduce (n, function (a, b) {return a.concat (b)})



0

이 시도:

i=new Array("aaaa", "bbbb");
j=new Array("cccc", "dddd");

i=i.concat(j);

@ reggie, 당신은 둘 다 같은 소스에서 복사하여 붙여 넣습니다;)
I.devries

아니요 귀하와 동일한 링크에서 정보를 확인했습니다. ilovethecode.com/Javascript/Javascript-Tutorials-How_To-Easy/...
하이로

D : 그래 ... 나는 우리가 동일한 소스에서 그것을 가지고 추측
레지을

적어도 @JAiro가 배열 내용을 변경했습니다. @ 레지하지 않았다. :)
dogbane

동일하다. 중요한 것은 사람들이 문제를 해결하도록 돕는 것이다 :)
JAiro

0

N 배열을 데이터베이스에서 가져 와서 하드 코딩하지 않은 경우 ES6을 사용하여 이와 같이 수행합니다.

let get_fruits = [...get_fruits , ...DBContent.fruit];
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.