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.


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


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]

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

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]

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

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 ]

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]

5

dipecahkan seperti ini.

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

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.


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]

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


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.


2

Dipendekkan dengan ES6.

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

Ini tidak concat dan unik yang beberapa array;

Demo di codepen


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



0

coba ini:

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

i=i.concat(j);

@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];
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.