Artikel ini termasuk keterampilan dasar JavaScript. Kami akan mempelajari berbagai metode umum untuk menggabungkan/menggabungkan dua array JS dan membandingkan kelebihan dan kekurangan dari berbagai metode.
Mari kita lihat skenario spesifik:
Salinan kode adalah sebagai berikut:
var q = [5, 5, 1, 9, 9, 6, 4, 5, 8];
var b = ["dasi", "mao", "csdn", "ren", "fu", "fei"];
Jelas, hasil dari penyambungan array q dan b sederhana adalah:
Salinan kode adalah sebagai berikut:
[
5, 5, 1, 9, 9, 6, 4, 5, 8,
"dasi", "mao", "csdn", "ren", "fu", "fei"
]
metode concat (..)
Penggunaan yang paling umum adalah sebagai berikut:
Salinan kode adalah sebagai berikut:
var c = q.concat (b);
Q; // [5,5,1,9,9,6,4,5,8]
B; // ["dasi", "mao", "csdn", "ren", "fu", "fei"];
C; // [5,5,1,9,9,6,4,5,8, "dasi", "mao", "csdn", "ren", "fu", "fei"]
Seperti yang Anda lihat, C adalah array baru yang mewakili kombinasi dua array: Q dan B, tetapi Q dan B tidak berguna sekarang, kan?
Jika array Q memiliki 10.000 elemen, dan array B memiliki 10.000 elemen? Kemudian array C sekarang memiliki 20.000 elemen, yang menempati dua kali memori.
"Ini baik -baik saja!", Anda mungkin berpikir. Taruh saja Q dan B sia -sia, dan kemudian akan dikumpulkan sampah, kan? Masalahnya sudah terpecahkan!
Salinan kode adalah sebagai berikut:
q = b = null; // `q` dan` b` sekarang dapat dikumpulkan sampah
Um? Jika arraynya kecil, maka secara alami tidak ada masalah. Namun, ketika array besar atau pemrosesan berulang diperlukan, memori terbatas, dan juga perlu dioptimalkan.
Penyisipan Loop
Oke, mari kita coba menambahkan isi array ke yang lain, menggunakan metode array#push ():
Salinan kode adalah sebagai berikut:
// Masukkan array `b` ke` q`
untuk (var i = 0; i <b.length; i ++) {
q.push (b [i]);
}
Q; // [5,5,1,9,9,6,4,5,8, "dasi", "mao", "csdn", "ren", "fu", "fei"]
b = null;
Sekarang, isi dari dua array asli disimpan dalam Q (Q + B).
Tampaknya telah melakukan pekerjaan pengoptimalan memori yang baik.
Tetapi bagaimana jika array Q sangat kecil dan B sangat besar? Untuk pertimbangan memori dan kecepatan, Anda ingin memasukkan Q yang lebih kecil ke depan B. Tidak masalah, cukup gunakan metode unshift () alih -alih push (), dan traversal yang sesuai harus dilakukan dari besar ke kecil:
Salinan kode adalah sebagai berikut:
// `q` ke` b`:
untuk (var i = q.length-1; i> = 0; i--) {
b.unshift (q [i]);
}
B; // [5,5,1,9,9,6,4,5,8, "dasi", "mao", "csdn", "ren", "fu", "fei"]
q = null;
Tips Praktis
Sayangnya, loop untuk pedesaan dan sulit dipertahankan. Bisakah kita melakukan yang lebih baik?
Mari kita coba array#kurangi dulu:
Salinan kode adalah sebagai berikut:
// `b` ke` q`:
q = b.reduce (function (coll, item) {
coll.push (item);
return coll;
}, Q );
Q; // [5,5,1,9,9,6,4,5,8, "dasi", "mao", "csdn", "ren", "fu", "fei"]
// atau `q` ke` b`:
b = q.reduceright (function (coll, item) {
coll.unshift (item);
return coll;
}, B );
B; // [5,5,1,9,9,6,4,5,8, "dasi", "mao", "csdn", "ren", "fu", "fei"]
Array#reduksi () dan array#reduceright () sangat kelas atas, tetapi sedikit besar, dan kebanyakan orang tidak dapat mengingatnya. Fungsi => panah (fungsi panah) dalam spesifikasi JS 6 dapat sangat mengurangi jumlah kode, tetapi membutuhkan panggilan fungsi untuk setiap elemen array, yang juga merupakan metode yang sangat buruk.
Jadi bagaimana dengan kode berikut?
Salinan kode adalah sebagai berikut:
// `b` ke` q`:
q.push.Apply (q, b);
Q; // [5,5,1,9,9,6,4,5,8, "dasi", "mao", "csdn", "ren", "fu", "fei"]
// atau `q` ke` b`:
B.unshift.Apply (B, Q);
B; // [5,5,1,9,9,6,4,5,8, "dasi", "mao", "csdn", "ren", "fu", "fei"]
Besar lebih tinggi, kan!? Secara khusus, metode unshift () tidak perlu mempertimbangkan urutan yang berlawanan seperti sebelumnya. Operator Ekspansi ES6 (Operator Spread, awalan) lebih canggih: A.Push (... b) atau b.unshift (... a)
Namun, pada kenyataannya, metode ini masih terlalu optimis. Dalam kedua kasus, apakah itu untuk lulus A atau B untuk menerapkan () sebagai parameter kedua (parameter pertama menjadi ini secara internal ketika fungsi panggilan dalam metode Apply, yaitu, konteks, ruang lingkup), atau ... metode operator ekspansi, array sebenarnya akan dipecah menjadi argumen fungsi.
Masalah utama pertama adalah bahwa ia menempati dua kali lipat memori (tentu saja, sementara!) Karena array perlu disalin ke dalam tumpukan fungsi. Selain itu, mesin JS yang berbeda memiliki algoritma implementasi yang berbeda, yang dapat membatasi jumlah parameter yang dapat dilewati fungsi.
Jika sebuah array menambahkan satu juta elemen, itu pasti akan melebihi ukuran yang diizinkan oleh tumpukan fungsi, apakah itu panggilan () atau panggilan unshift (). Metode ini hanya tersedia ketika ada beberapa ribu elemen, jadi harus dibatasi untuk melebihi rentang tertentu.
Catatan: Anda juga dapat mencoba splice (), dan Anda pasti akan menemukan bahwa ia memiliki batasan yang sama dengan dorong (..)/unshift (..).
Salah satu opsi adalah terus menggunakan metode ini, tetapi dengan pemrosesan batch:
Salinan kode adalah sebagai berikut:
function combineinto (q, b) {
var len = q.length;
untuk (var i = 0; i <len; i = i+5000) {
// 5.000 item diproses sekaligus
b.unshift.Apply (B, Q.Slice (i, i+5000));
}
}
Tunggu, kami mengkompromikan keterbacaan kode (bahkan kinerja!). Akhiri perjalanan ini sebelum kita menyerah.
Meringkaskan
Array#concat () adalah metode yang dicoba dan diuji untuk menggabungkan dua (atau lebih) array. Tapi dia menciptakan array baru alih -alih memodifikasi yang sudah ada.
Ada banyak cara untuk beradaptasi, tetapi mereka semua memiliki kelebihan dan kekurangan yang berbeda dan perlu dipilih sesuai dengan kondisi aktual.
Berbagai keuntungan/kerugian tercantum di atas, dan mungkin metode terbaik (termasuk yang tidak terdaftar) dikurangi (..) dan reduceright (..)
Apa pun yang Anda pilih, Anda harus berpikir kritis tentang kombinasi dan strategi Anda daripada menerima begitu saja.