Dengan asumsi saya memiliki sebuah array yang memiliki ukuran N
(di mana N > 0
), apakah ada cara yang lebih efisien untuk membuat ulang array yang tidak memerlukan langkah-langkah O (N +1)?
Dalam kode, pada dasarnya, apa yang saya lakukan saat ini adalah
function prependArray(value, oldArray) {
var newArray = new Array(value);
for(var i = 0; i < oldArray.length; ++i) {
newArray.push(oldArray[i]);
}
return newArray;
}
javascript
arrays
prepend
samcone
sumber
sumber
Jawaban:
Saya tidak yakin tentang lebih efisien dalam hal big-O tetapi tentu saja menggunakan
unshift
metode ini lebih ringkas:[Sunting]
Benchmark jsPerf ini menunjukkan bahwa
unshift
lebih cepat dalam setidaknya beberapa browser, terlepas dari kinerja O besar yang mungkin berbeda jika Anda ok dengan memodifikasi array di tempat. Jika Anda benar-benar tidak dapat mengubah array asli maka Anda akan melakukan sesuatu seperti cuplikan di bawah ini, yang sepertinya tidak jauh lebih cepat daripada solusi Anda:[Sunting 2]
Untuk kelengkapan, fungsi berikut dapat digunakan sebagai ganti contoh OP
prependArray(...)
untuk memanfaatkanunshift(...)
metode Array :sumber
prepend
"unshift
"?unshift
terdengar lebih tepat untuk operasi array seperti itu (itu menggerakkan elemen ... lebih atau kurang secara fisik).prepend
akan lebih tepat untuk daftar tertaut, di mana Anda benar-benar menambahkan elemen.push
danunshift
keduanya mengandungu
, sedangkanpop
danshift
tidak punya.Dengan ES6, Anda sekarang dapat menggunakan operator spread untuk membuat array baru dengan elemen baru Anda dimasukkan sebelum elemen asli.
Pembaruan 2018-08-17: Kinerja
Saya bermaksud jawaban ini untuk menyajikan sintaks alternatif yang saya pikir lebih berkesan dan ringkas. Perlu dicatat bahwa menurut beberapa tolok ukur (lihat jawaban lain ini ), sintaks ini secara signifikan lebih lambat. Ini mungkin tidak akan menjadi masalah kecuali Anda melakukan banyak operasi ini dalam satu lingkaran.
sumber
unshift
Jika Anda menambahkan sebuah array ke bagian depan array lain, itu lebih efisien untuk digunakan saja
concat
. Begitu:Tapi ini masih akan menjadi O (N) dalam ukuran oldArray. Namun, ini lebih efisien daripada iterasi manual di atas oldArray. Juga, tergantung pada detailnya, ini dapat membantu Anda, karena jika Anda akan menambahkan banyak nilai, lebih baik untuk meletakkannya ke dalam array terlebih dahulu dan kemudian menyelesaikan oldArray di akhir, daripada menambahkan masing-masing secara terpisah.
Tidak ada cara untuk berbuat lebih baik daripada O (N) dalam ukuran oldArray, karena array disimpan dalam memori yang berdekatan dengan elemen pertama dalam posisi tetap. Jika Anda ingin memasukkan sebelum elemen pertama, Anda harus memindahkan semua elemen lainnya. Jika Anda perlu cara lain, lakukan apa yang dikatakan @GWW dan gunakan daftar tertaut, atau struktur data yang berbeda.
sumber
unshift
. Tetapi perhatikan bahwa a) yang bermutasi oldArray sedangkanconcat
tidak (jadi mana yang lebih baik untuk Anda tergantung pada situasinya), dan b) itu hanya memasukkan satu elemen.[0]
), sedangkan unshift bermutasi di tempat. Tetapi keduanya harus O (N). Juga sorakan untuk tautan ke situs itu - terlihat sangat berguna.Jika Anda ingin menambahkan array (a1 dengan array a2), Anda bisa menggunakan yang berikut ini:
sumber
Jika Anda perlu mempertahankan array lama, potong yang lama dan lepaskan nilai yang baru ke awal slice.
sumber
Saya memiliki beberapa tes baru dari berbagai metode prapengisian. Untuk array kecil (<1000 elem) pemimpin adalah untuk siklus ditambah dengan metode dorong. Untuk array besar, metode Unshift menjadi pemimpin.
Tetapi situasi ini sebenarnya hanya untuk browser Chrome. Di Firefox unshift memiliki optimasi yang luar biasa dan lebih cepat dalam semua kasus.
Penyebaran ES6 100 kali lebih lambat di semua browser.
https://jsbench.me/cgjfc79bgx/1
sumber
Ada metode khusus:
Tetapi jika Anda ingin menambahkan beberapa elemen ke array, akan lebih cepat menggunakan metode seperti ini:
sumber
Array.prototype.unshift.apply(a,b);
Contoh untuk menambahkan di tempat:
sumber
Memanggil
unshift
hanya mengembalikan panjang array baru. Jadi, untuk menambahkan elemen di awal dan mengembalikan array baru, saya melakukan ini:atau cukup dengan operator spread:
Dengan cara ini, array asli tetap tidak tersentuh.
sumber