N個の配列を連結する最も効率的な方法は何ですか?


回答:


323

3つ以上の配列を連結している場合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];

2つの配列のみを連結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)

ただし、大規模な配列(メンバー数が100,000以上)の場合、要素の配列をpushapply()ECMAScript 2015スプレッドオペレーターを使用して)に渡す手法は失敗する可能性があります。このような配列では、ループを使用する方が適切です。https://stackoverflow.com/a/17368101/96100を参照してくださいを参照してください。


1
私はあなたのテストにエラーがあるかもしれないと信じています:a.concat(b)テストケースは不必要に配列のコピーを作成しaてからそれを捨てているようです。
ninjagecko 2012

1
@ninjagecko:その通りです。私はそれを更新しました:jsperf.com/concatperftest/6。2つの既存の配列を連結する新しい配列を作成する特定のケースでconcat()は、一般的に高速に表示されます。配列を既存の配列に連結して配置する場合のpush()方法です。回答を更新しました。
Tim Down

16
push.applyメソッドを使用して単一の配列をいくつかの新しい配列で拡張すると、単純なconcat呼び出しよりもパフォーマンスが大幅に向上する(約100倍)ことを証明できます。私はv8 / node.jsで、整数の短いリストの非常に長いリストを処理しています。
chbrown 2012

1
さらに簡潔な方法は、a.push(... b);です。
dinvlad 2017年

1
@dinvlad:True、ただし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 2012

IMOこれは、n個の配列を「マージ」する最も効果的な方法です。よくできました
Eric Uldall

この答えは、任意の長さの配列の配列があり、それらをすべて連結したい場合など、Nが事前にわからない場合に特に役立ちます。
jfriend00

3
ES6とスプレッド演算子を使用すると、さらに簡単になります:[] .concat(... [array1、array2、...])さて、2番目の3つのドットは少し残念です。最初の3つは、スプレッドオペレーター developer.mozilla.org/en/docs/Web/JavaScript/Reference/…です
Eydrian

アイドリアン:個人的にはスプレッド演算子を非効率的にしようとしますが、それは非常に非効率的ですが、それが実装が未成熟であるためか、es6仕様のセマンティクスが少し重いリフティングを必要とするためか(つまり、決して改善されないため) )。ただし、この特定のケースではベンチマークを実行していません。
ninjagecko 2017

34

ES2015(ES6)をご利用の方

これで、Spread Syntaxを使用して配列を連結できます。

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()メソッドは、2つ以上の配列を結合するために使用されます。既存の配列は変更されません。結合された配列のコピーが返されるだけです。

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

map / filter / sortなどを介して結果をパイプ処理している最中に配列の配列を連結したい場合は、 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

これは実際には、より大きなアレイボリュームではかなりひどく非効率的です。 jsperf.com/flatten-array-203948 [].concat.apply([], ...arr)は、大容量でのパフォーマンスが大幅に向上します。
学長

7

これで、を使用して複数の配列を組み合わせることができますES6 Spread。を使用concat()して配列を連結する代わりに、spread構文を使用して複数の配列を1つの平坦化された配列に結合してみてください。例えば:

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

完璧なソリューション。
ネヘム

4

jsperf.comサイトを使用してパフォーマンスを比較できます。ここに連結へのリンクがありますます。

以下の比較を追加しました:

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

もう1つは、クロームでほぼ10倍遅いです。


ただし、を使用できますpush.apply()。これは、concat()Chromeを除くすべてのブラウザよりも高速であるようです。私の答えを見てください。
Tim Down


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

または、spreadオペレーターなしで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

新しいSet([]。concat(... Array));を使用したい しかし、1つの式で重複を削除したいのですが。出来ますか ?
Krunal Shah

2

プッシュで配列をマージ

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

ConcatおよびSpreadオペレーターの使用

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/...
JAIRO

うん...同じソースから入手したと思う:D
レジー

少なくとも@JAiroが配列の内容を変更しました。@reggieはしませんでした。:)
dogbane

それは同じです、重要なことは人々がその問題を解決するのを助けることです:)
JAiro

0

N個の配列がデータベースから取得され、ハードコーディングされていない場合、ES6を使用してこのようにします

let get_fruits = [...get_fruits , ...DBContent.fruit];
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.