Tampaknya tidak ada cara untuk memperluas array JavaScript yang ada dengan array lain, yaitu meniru extend
metode Python .
Saya ingin mencapai yang berikut:
>>> a = [1, 2]
[1, 2]
>>> b = [3, 4, 5]
[3, 4, 5]
>>> SOMETHING HERE
>>> a
[1, 2, 3, 4, 5]
Saya tahu ada a.concat(b)
metode, tetapi menciptakan array baru alih-alih hanya memperpanjang yang pertama. Saya ingin algoritma yang bekerja secara efisien bila a
jauh lebih besar daripada b
(yaitu yang tidak menyalin a
).
Catatan: Ini bukan duplikat dari Bagaimana cara menambahkan sesuatu ke array? - tujuannya di sini adalah untuk menambahkan seluruh konten dari satu array ke array lainnya, dan untuk melakukannya "di tempat", yaitu tanpa menyalin semua elemen dari array yang diperluas.
javascript
arrays
concatenation
DzinX
sumber
sumber
a.push(...b)
. Konsepnya mirip dengan jawaban teratas, tetapi diperbarui untuk ES6.Jawaban:
The
.push
Metode dapat mengambil beberapa argumen. Anda bisa menggunakan operator spread untuk meneruskan semua elemen array kedua sebagai argumen untuk.push
:Jika browser Anda tidak mendukung ECMAScript 6, Anda dapat menggunakannya
.apply
:Atau mungkin, jika Anda pikir itu lebih jelas:
Harap dicatat bahwa semua solusi ini akan gagal dengan kesalahan stack overflow jika array
b
terlalu panjang (masalah dimulai pada sekitar 100.000 elemen, tergantung pada browser).Jika Anda tidak dapat menjamin bahwa
b
itu cukup singkat, Anda harus menggunakan teknik berbasis loop standar yang dijelaskan dalam jawaban lainnya.sumber
push
Metode Array dapat mengambil sejumlah argumen, yang kemudian didorong ke belakang array. Begitua.push('x', 'y', 'z')
juga panggilan yang valid yang akan diperpanjanga
oleh 3 elemen.apply
adalah metode dari setiap fungsi yang mengambil array dan menggunakan elemen-elemennya seolah-olah mereka semua diberikan secara eksplisit sebagai elemen posisi ke fungsi. Begitua.push.apply(a, ['x', 'y', 'z'])
juga akan memperluas array dengan 3 elemen. Selain itu,apply
gunakan konteks sebagai argumen pertama (kami sampaikana
lagi di sana untuk ditambahkan kea
).[].push.apply(a, b)
.Update 2018 : Sebuah jawaban yang lebih baik adalah salah satu yang lebih baru saya :
a.push(...b)
. Jangan pilih yang ini lagi, karena tidak pernah benar-benar menjawab pertanyaan, tapi itu adalah hack 2015 di-hit-on-Google :)Bagi mereka yang hanya mencari "memperpanjang array JavaScript" dan sampai di sini, Anda dapat menggunakannya dengan sangat baik
Array.concat
.Concat akan mengembalikan salinan array baru, karena thread starter tidak mau. Tapi Anda mungkin tidak peduli (tentu untuk sebagian besar penggunaan ini tidak masalah).
Ada juga beberapa gula ECMAScript 6 yang bagus untuk ini dalam bentuk operator spread:
(Ini juga salinan.)
sumber
arr.push(...arr2)
ini lebih baru dan lebih baik dan jawaban yang benar secara teknis untuk pertanyaan khusus ini.Anda harus menggunakan teknik berbasis loop. Jawaban lain pada halaman ini yang didasarkan pada penggunaan
.apply
dapat gagal untuk array besar.Implementasi berbasis loop yang cukup singkat adalah:
Anda kemudian dapat melakukan hal berikut:
Jawaban DzinX (menggunakan push.apply) dan
.apply
metode berbasis lainnya gagal ketika array yang kita tambahkan besar (tes menunjukkan bahwa bagi saya besar adalah> 150.000 entri kira-kira di Chrome, dan> 500.000 entri di Firefox). Anda dapat melihat kesalahan ini terjadi di jsperf ini .Terjadi kesalahan karena ukuran tumpukan panggilan terlampaui ketika 'Function.prototype.apply' dipanggil dengan array besar sebagai argumen kedua. (MDN memiliki catatan tentang bahaya melebihi ukuran tumpukan panggilan menggunakan Function.prototype.apply - lihat bagian berjudul "Terapkan dan fungsi bawaan ".)
Untuk perbandingan kecepatan dengan jawaban lain di halaman ini, lihat jsperf ini (terima kasih kepada EaterOfCode). Implementasi berbasis loop serupa dalam kecepatan untuk menggunakan
Array.push.apply
, tetapi cenderung sedikit lebih lambat daripadaArray.slice.apply
.Menariknya, jika array yang Anda tambahkan jarang,
forEach
metode berbasis di atas dapat mengambil keuntungan dari sparsity dan mengungguli.apply
metode berbasis; lihat jsperf ini jika Anda ingin menguji sendiri.By the way, jangan tergoda (seperti saya!) Untuk lebih mempersingkat implementasi forEach ke:
karena ini menghasilkan hasil sampah! Mengapa? Karena
Array.prototype.forEach
menyediakan tiga argumen untuk fungsi yang dipanggil - ini adalah: (element_value, element_index, source_array). Semua ini akan didorong ke array pertama Anda untuk setiap iterasiforEach
jika Anda menggunakan "forEach (this.push, this)"!sumber
.push.apply
sebenarnya jauh lebih cepat daripada.forEach
di v8, yang tercepat masih merupakan inline loop..forEach
lebih cepat daripada.push.apply
di Chrome / Chromium (di semua versi sejak v25). Saya belum dapat menguji v8 secara terpisah, tetapi jika Anda memiliki harap tautkan hasil Anda. Lihat jsperf: jsperf.com/array-extending-push-vs-concat/5undefined
, maka.forEach
akan melewatkannya, menjadikannya yang tercepat..splice
sebenarnya yang tercepat ?! jsperf.com/array-extending-push-vs-concat/18Saya merasa yang paling elegan hari ini adalah:
The Artikel MDN pada operator penyebaran menyebutkan ini cara manis yang bagus di ES2015 (ES6):
Perhatikan bahwa
arr2
tidak boleh besar (simpan di bawah sekitar 100.000 item), karena tumpukan panggilan meluap, sesuai jawaban jcdude.sumber
arr1.push(arr2)
. Ini bisa menjadi masalah seperti sehinggaarr1 = []; arr2=['a', 'b', 'd']; arr1.push(arr2)
hasilnya menjadi array arrayarr1 == [['a','b','d']]
daripada dua array yang digabungkan. Ini adalah kesalahan yang mudah dibuat. Saya lebih suka jawaban kedua Anda di bawah ini karena alasan ini. stackoverflow.com/a/31521404/4808079.concat
adalah bahwa argumen kedua tidak boleh berupa array. Ini dapat dicapai dengan menggabungkan operator spread denganconcat
, mis.arr1.push(...[].concat(arrayOrSingleItem))
Pertama beberapa kata tentang
apply()
dalam JavaScript untuk membantu memahami mengapa kami menggunakannya:Push mengharapkan daftar item untuk ditambahkan ke array. The
apply()
metode, bagaimanapun, mengambil argumen diharapkan untuk panggilan fungsi sebagai array. Ini memungkinkan kita untuk dengan mudahpush
elemen dari satu array ke array lain denganpush()
metode bawaan .Bayangkan Anda memiliki susunan ini:
dan cukup lakukan ini:
Hasilnya adalah:
Hal yang sama dapat dilakukan di ES6 menggunakan operator spread ("
...
") seperti ini:Lebih pendek dan lebih baik tetapi tidak sepenuhnya didukung di semua browser saat ini.
Juga jika Anda ingin memindahkan semuanya dari array
b
kea
, mengosongkanb
dalam proses, Anda dapat melakukan ini:dan hasilnya adalah sebagai berikut:
sumber
while (b.length) { a.push(b.shift()); }
benar?Jika Anda ingin menggunakan jQuery, ada $ .merge ()
Contoh:
Hasil: a =
[1, 2, 3, 4, 5]
sumber
jQuery.merge()
?Saya suka
a.push.apply(a, b)
metode yang dijelaskan di atas, dan jika mau, Anda selalu dapat membuat fungsi perpustakaan seperti ini:dan gunakan seperti ini
sumber
Dimungkinkan untuk melakukannya menggunakan
splice()
:Tetapi meskipun lebih jelek itu tidak lebih cepat daripada
push.apply
, setidaknya tidak di Firefox 3.0.sumber
Solusi ini cocok untuk saya (menggunakan operator spread dari ECMAScript 6):
sumber
Anda dapat membuat polyfill untuk ekstensi seperti yang saya miliki di bawah ini. Ini akan menambah array; di tempat dan kembalikan sendiri, sehingga Anda dapat memadukan metode lain.
sumber
Menggabungkan jawaban ...
sumber
Solusi lain untuk menggabungkan lebih dari dua array
Kemudian panggil dan cetak sebagai:
Output akan menjadi:
Array [1, 2, 3, 4, 5, 6, 7]
sumber
Jawabannya sangat sederhana.
Concat bertindak sangat mirip dengan penggabungan string JavaScript. Ini akan mengembalikan kombinasi parameter yang Anda masukkan ke fungsi concat di akhir array yang Anda panggil fungsi. Intinya adalah bahwa Anda harus menetapkan nilai yang dikembalikan ke variabel atau hilang. Jadi misalnya
sumber
Array.prototype.concat()
di MDN ini akan mengembalikan Array baru , itu tidak akan menambahkan ke array yang ada seperti OP jelas bertanya.Gunakan
Array.extend
alih-alihArray.push
untuk> 150.000 rekaman.sumber
Sangat sederhana, tidak mengandalkan operator yang tersebar atau berlaku, jika itu masalah.
Setelah menjalankan beberapa tes kinerja, ini sangat lambat, tetapi menjawab pertanyaan sehubungan dengan tidak membuat array baru. Concat secara signifikan lebih cepat, bahkan jQuery
$.merge()
mengatasinya.https://jsperf.com/merge-arrays19b/1
sumber
.forEach
daripada.map
jika Anda tidak menggunakan nilai kembali. Lebih baik menyampaikan maksud kode Anda..map
tetapi Anda juga bisa melakukannyab.forEach(function(x) { a.push(x)} )
. Sebenarnya saya menambahkan itu ke tes jsperf dan itu rambut lebih cepat dari peta. Masih sangat lambat..map
sini terlihat sangat aneh. Itu seperti meneleponb.filter(x => a.push(x))
. Ini berfungsi, tetapi membingungkan pembaca dengan menyiratkan sesuatu sedang terjadi padahal tidak..map()
terjadi dan itu masalahnya. Pengetahuan ini akan membuat saya berpikir Anda memerlukan array yang dihasilkan, jika tidak maka akan menjadi hal yang baik untuk digunakan.forEach()
untuk membuat pembaca berhati-hati tentang efek samping dari fungsi callback. Secara tegas, solusi Anda menciptakan array tambahan bilangan asli (hasilpush
), sedangkan pertanyaannya menyatakan: "tanpa membuat array baru".