Saya memiliki dua array. Larik pertama berisi beberapa nilai sedangkan larik kedua berisi indeks nilai yang harus dihapus dari larik pertama. Sebagai contoh:
var valuesArr = new Array("v1","v2","v3","v4","v5");
var removeValFromIndex = new Array(0,2,4);
Saya ingin menghapus nilai yang ada di indeks 0,2,4
dari valuesArr
. Saya pikir splice
metode asli mungkin membantu jadi saya datang dengan:
$.each(removeValFromIndex,function(index,value){
valuesArr.splice(value,1);
});
Tetapi itu tidak berhasil karena setelah masing-masing splice
, indeks nilai di dalamnya valuesArr
berbeda. Saya bisa menyelesaikan masalah ini dengan menggunakan array sementara dan menyalin semua nilai ke array kedua, tetapi saya bertanya-tanya apakah ada metode asli yang dapat kami lewati beberapa indeks untuk menghapus nilai dari array.
Saya lebih suka solusi jQuery. (Tidak yakin apakah saya bisa menggunakan di grep
sini)
sumber
$.each(rvm.reverse(), function(e, i ) {})
removeValFromIndex
diurutkan dalam urutan menaikIni salah satu yang saya gunakan saat tidak menggunakan lodash / garis bawah:
sumber
slice
Anda harus menghitung ulang indeks yang akan dihapus (-1 onIndexestoBeRemoved
), tetapi itu benar-benar berfungsi!IndexesToBeRemoved
array yang diurutkan secara ascending.IndexesToBeRemoved
diurutkan (naik).Tidak
in-place
tetapi dapat dilakukan dengan menggunakangrep
daninArray
fungsijQuery
.periksa biola ini .
sumber
valuesArr = $.grep(...);
Saya sarankan Anda menggunakan Array.prototype.filter
sumber
Referensi MDN ada di sini
sumber
Dalam JS murni Anda dapat melakukan perulangan melalui array ke belakang, jadi
splice()
tidak akan mengacaukan indeks elemen berikutnya dalam perulangan:sumber
Rasanya perlu mengirim jawaban dengan
O(n)
waktu :). Masalah dengan solusi sambatan adalah karena implementasi yang mendasari array secara harfiah adalah array , setiapsplice
panggilan akan memakanO(n)
waktu. Ini paling jelas saat kami menyiapkan contoh untuk mengeksploitasi perilaku ini:Ini menghapus elemen mulai dari tengah ke awal, oleh karena itu setiap menghapus memaksa mesin js untuk menyalin
n/2
elemen, kami memiliki(n/2)^2
operasi penyalinan total yang kuadrat.Solusi sambungan (dengan asumsi
is
sudah diurutkan dalam urutan menurun untuk menghilangkan overhead) berjalan seperti ini:Namun, tidak sulit untuk mengimplementasikan solusi waktu linier, dengan membangun kembali array dari awal, menggunakan mask untuk melihat apakah kita menyalin elemen atau tidak (sort akan mendorong ini ke
O(n)log(n)
). Berikut ini adalah implementasi seperti itu (bukanmask
boolean terbalik untuk kecepatan):Saya menjalankan ini di jsperf.com dan bahkan
n=100
metode sambungannya 90% lebih lambat. Untuk lebih besarn
perbedaan ini akan jauh lebih besar.sumber
ES6 cepat satu liner:
sumber
removeValFromIndex
sebuahSet()
dan menggunakanremoveValFromIndex.has
bukanincludes
.Solusi sederhana dan efisien (kompleksitas linier) menggunakan filter dan Set :
Keuntungan besar dari implementasi itu adalah bahwa operasi Set lookup (
has
fungsi) membutuhkan waktu yang konstan, menjadi lebih cepat daripada jawaban nevace, misalnya.sumber
Ini berfungsi dengan baik untuk saya dan berfungsi saat menghapus dari larik objek juga:
Mungkin ada cara yang lebih singkat dan lebih efisien untuk menulis ini, tetapi ini berhasil.
sumber
Solusi sederhana menggunakan ES5. Ini tampaknya lebih sesuai untuk sebagian besar aplikasi saat ini, karena banyak yang tidak lagi ingin bergantung pada jQuery dll.
Saat indeks yang akan dihapus diurutkan dalam urutan menaik:
Ketika indeks yang akan dihapus tidak diurutkan:
sumber
Anda dapat memperbaiki kode Anda dengan mengganti
removeValFromIndex
denganremoveValFromIndex.reverse()
. Jika larik tersebut tidak dijamin untuk menggunakan urutan naik, Anda dapat menggunakanremoveValFromIndex.sort(function(a, b) { return b - a })
.sumber
removeValFromIndex
urutan menaik.Inilah satu kemungkinan:
Contoh di jsFiddle
MDN di Array.prototype.reduceRight
sumber
Jika Anda menggunakan underscore.js , Anda dapat menggunakannya
_.filter()
untuk memecahkan masalah Anda.Selain itu, jika Anda mencoba menghapus item menggunakan daftar item, bukan indeks, Anda dapat menggunakan
_.without()
, seperti:Sekarang
filteredArr
harus["V2", "V4", "V5"]
sumber
filter + indexOf (IE9 +):
Atau dengan filter ES6 + temukan (Edge +):
sumber
Ini quickie.
sumber
Kedengarannya Apply bisa jadi apa yang Anda cari.
mungkin sesuatu seperti ini akan berhasil?
sumber
.splice()
metode ini tidak mengharapkan daftar elemen yang akan dihapus, metode ini mengharapkan indeks tunggal elemen yang akan mulai dihapus diikuti dengan jumlah elemen yang akan dihapus ...Untuk Beberapa item atau item unik:
Saya sarankan Anda menggunakan Array.prototype.filter
Jangan pernah menggunakan indexOf jika Anda sudah mengetahui indeksnya !:
Melakukan:
dengan Hash ... menggunakan Array.prototype.map
sumber
Ini bekerja. Namun, Anda akan membuat array baru dalam prosesnya. Tidak yakin apakah itu yang Anda inginkan atau tidak, tetapi secara teknis itu akan menjadi array yang hanya berisi nilai yang Anda inginkan.
sumber
Anda dapat mencoba dan menggunakan
delete array[index]
Ini tidak akan sepenuhnya menghapus elemen melainkan menetapkan nilainya keundefined
.sumber
Anda dapat membuat a
Set
dari larik dan kemudian membuat larik dari himpunan.sumber