Apa cara paling efisien untuk menggabungkan array N?

Jawaban:

323

Jika Anda menggabungkan lebih dari dua array, concat()adalah cara untuk mencari kenyamanan dan kemungkinan performa.

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

Untuk menggabungkan hanya dua array, fakta yang pushmenerima banyak argumen yang terdiri dari elemen untuk ditambahkan ke array dapat digunakan sebagai gantinya untuk menambahkan elemen dari satu array ke akhir array tanpa menghasilkan array baru. Dengan slice()itu juga dapat digunakan sebagai pengganti concat()tetapi tampaknya tidak ada keuntungan kinerja dari melakukan ini .

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

Dalam ECMAScript 2015 dan yang lebih baru, ini dapat dikurangi lebih jauh ke

a.push(...b)

Namun, tampaknya untuk array besar (dari urutan 100.000 anggota atau lebih), teknik melewati array elemen ke push(baik menggunakan apply()atau operator spread ECMAScript 2015) dapat gagal. Untuk array seperti itu, menggunakan loop adalah pendekatan yang lebih baik. Lihat https://stackoverflow.com/a/17368101/96100 untuk detailnya.

Tim Down
sumber
1
Saya percaya pengujian Anda mungkin memiliki kesalahan: a.concat(b)test case sepertinya tidak perlu membuat salinan array akemudian membuangnya.
ninjagecko
1
@ninjagecko: Anda benar. Saya memperbaruinya: jsperf.com/concatperftest/6 . Untuk kasus khusus membuat array baru yang menggabungkan dua array yang ada, tampaknya concat()umumnya lebih cepat. Untuk kasus menggabungkan array ke array yang ada di tempat, push()adalah cara untuk pergi. Saya memperbarui jawaban saya.
Tim Down
16
Saya bisa membuktikan bahwa memperluas satu array dengan beberapa array baru menggunakan metode push.apply menganugerahkan keuntungan kinerja yang sangat besar (~ 100x) dibandingkan panggilan concat sederhana. Saya berurusan dengan daftar bilangan bulat pendek, di v8 / node.js.
chbrown
1
Cara yang lebih ringkas adalah a.push (... b);
dinvlad
1
@dinvlad: Benar, tetapi hanya di lingkungan ES6. Saya telah menambahkan catatan untuk jawaban saya.
Tim Down
158
[].concat.apply([], [array1, array2, ...])

sunting : bukti efisiensi: http://jsperf.com/multi-array-concat/7

edit2 : Tim Supinie menyebutkan dalam komentar bahwa ini dapat menyebabkan penafsir melebihi ukuran panggilan stack. Ini mungkin tergantung pada mesin js, tapi saya juga mendapatkan "Ukuran stack panggilan maksimum terlampaui" di Chrome. Kasus uji: [].concat.apply([], Array(300000).fill().map(_=>[1,2,3])). (Saya juga mendapatkan kesalahan yang sama dengan menggunakan jawaban yang saat ini diterima, jadi seseorang mengantisipasi kasus penggunaan tersebut atau membangun perpustakaan untuk orang lain, pengujian khusus mungkin diperlukan tidak peduli solusi mana yang Anda pilih.)

ninjagecko
sumber
3
@ c69: sepertinya seefisien jawaban yang dipilih berulang kali .push (#, #, ..., #), setidaknya di Chrome. jsperf.com/multi-array-concat Jawaban yang dipilih oleh Tim Down mungkin juga memiliki kesalahan di dalamnya. Tautan ini adalah perbandingan kinerja bergabung dengan banyak array sebagai pertanyaan yang diajukan (bukan hanya 2); beberapa kemungkinan panjang diuji.
ninjagecko
IMO ini adalah cara paling efektif untuk "menggabungkan" n array, dilakukan dengan baik
Eric Uldall
Jawaban ini sangat berguna ketika N tidak diketahui sebelumnya seperti ketika Anda memiliki array array yang sewenang-wenang dan Anda ingin semuanya disatukan.
jfriend00
3
Dengan ES6 dan operator spread, ini menjadi lebih sederhana: [] .concat (... [array1, array2, ...]) Ya, tiga titik kedua agak disayangkan. Tiga pertama adalah penyebaran Operator developer.mozilla.org/en/docs/Web/JavaScript/Reference/...
Eydrian
Eydrian: Saya pribadi mencoba menghindari operator penyebaran karena sangat tidak efisien, tetapi saya belum yakin apakah itu karena implementasinya belum matang, atau semantik dari spesifikasi es6 memerlukan sedikit pengangkatan yang lebih berat (yaitu tidak akan pernah menjadi lebih baik ). Belum menjalankan tolok ukur apa pun dalam kasus khusus ini.
ninjagecko
34

Untuk orang yang menggunakan ES2015 (ES6)

Anda sekarang dapat menggunakan Sintaks Penyebaran untuk menggabungkan array:

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]
Duncan Luk
sumber
Seberapa efisienkah ini? Dari apa yang telah saya uji, ini sangat lambat untuk array yang berisi objek, lihat: jsperf.com/array-concat-vs-array-push-vs-array-spread/1
hitautodestruct
28

The concat()metode yang digunakan untuk menggabungkan dua atau lebih array. Itu tidak mengubah array yang ada, itu hanya mengembalikan salinan dari array yang bergabung.

array1 = array1.concat(array2, array3, array4, ..., arrayN);
dogbane
sumber
1
Terkadang saya membenci JavaScript karena tidak memodifikasi array asli. 🙄
Vincent Hoch-Drei
@ VincentHoch-Drei concatsecara khusus digunakan untuk membuat array baru tanpa mengubah array asli. Jika Anda ingin memperbarui array1, Anda harus menggunakanarray1.push(...array2, ...array3, ...array4)
adiga
24

Gunakan Array.prototype.concat.apply untuk menangani rangkaian beberapa array:

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

Contoh:

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]
Burnee
sumber
1
Saya suka yang ini! Bekerja dengan mudah dengan sejumlah variabel array untuk digabungkan. +1
Joel
14

Jika Anda berada di tengah perpipaan hasilnya melalui peta / filter / semacam dll dan Anda ingin membuat array array, Anda dapat menggunakan 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']
artnikpro
sumber
14

Untuk berbagai array dan ES6, gunakan

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

Sebagai contoh:

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 ]
David
sumber
1
Selain itu, Anda dapat menghapus elemen duplikat dengan menggunakan newArr = Array.from(new Set(newArr));.
Darius M.
Mengapa dalam naskah ini menjadi any[]? Pengetikan ada - aneh.
Simon_Weaver
Ini sebenarnya sangat tidak efisien pada volume array yang lebih besar. jsperf.com/flatten-array-203948 [].concat.apply([], ...arr) berkinerja jauh lebih baik pada volume besar.
colemars
7

Sekarang kita bisa menggabungkan banyak array menggunakan ES6 Spread. Alih-alih menggunakan concat()untuk menggabungkan array, coba gunakan sintaks spread untuk menggabungkan beberapa array menjadi satu array yang rata. misalnya:

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]
chinmayan
sumber
5

dipecahkan seperti ini.

let arr = [[1, 2], [3, 4], [5, 6]];
 console.log([].concat(...arr));
Th1
sumber
Solusi sempurna.
nehem
4

Anda dapat menggunakan situs jsperf.com untuk membandingkan kinerja. Berikut ini tautan ke konser .

Menambahkan perbandingan antara:

var c = a.concat(b);

dan:

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

Yang kedua hampir 10 kali lebih lambat di chrome.

gor
sumber
Namun, Anda dapat menggunakan push.apply(), yang tampaknya lebih cepat daripada concat()di semua browser kecuali Chrome. Lihat jawaban saya.
Tim Down
3

Berikut adalah fungsi di mana Anda dapat menggabungkan beberapa jumlah array

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

    return newArr;
}

Contoh -

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

akan menampilkan

[1,2,3,5,2,1,4,2,8,9]
Koushik Das
sumber
3

Gabungkan Array dengan Push:

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

Menggunakan operator Concat dan 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);

Zobia Kanwal
sumber
2

Jika Anda memiliki array array dan ingin menggabungkan elemen menjadi satu array, coba kode berikut (Membutuhkan 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];

Atau jika Anda menyukai pemrograman fungsional

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

Atau bahkan lebih baik dengan sintaks ES5, tanpa operator spread

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

Cara ini berguna jika Anda tidak tahu tidak. array pada waktu kode.

cupu
sumber
2

Dipendekkan dengan ES6.

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

Ini tidak concat dan unik yang beberapa array;

Demo di codepen

ronaldtgi
sumber
tidak tetapi menghapus duplikat .. bagaimana jika saya tidak ingin menghapus duplikat array?
Krunal Shah
new Set()tidak menghapus item yang digandakan. Hapus saja. [].concat(...Array)
ronaldtgi
saya ingin menggunakan Set baru [[]. concat (... Array)); tetapi saya juga ingin menghapus duplikat bersama dengannya dalam satu ekspresi. apa itu mungkin ?
Krunal Shah
1

di mana 'n' adalah sejumlah array, mungkin array array. . .

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

rashadb
sumber
0

coba ini:

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

i=i.concat(j);
Jairo
sumber
@reggie, Anda berdua menyalin-paste dari sumber yang sama;)
I.devries
tidak, saya sudah memeriksa info di tautan yang sama dengan Anda. ilovethecode.com/Javascript/Javascript-Tutorials-How_To-Easy/…
JAiro
yeah ... Saya kira kita mendapatkannya dari sumber yang sama: D
reggie
setidaknya @JAiro mengubah isi array. @reggie tidak. :)
dogbane
itu sama, yang penting adalah membantu orang untuk menyelesaikan masalahnya :)
JAiro
0

jika array N didapat dari basis data dan bukan hardcoded, saya akan melakukannya seperti ini menggunakan ES6

let get_fruits = [...get_fruits , ...DBContent.fruit];
Akinnifesi Damilola
sumber