var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
Bagaimana cara menghapus objek dari array dengan mencocokkan properti objek?
Tolong hanya JavaScript asli.
Saya mengalami masalah saat menggunakan sambungan karena panjangnya berkurang dengan setiap penghapusan. Menggunakan clone dan splicing pada orignal index masih menyisakan masalah panjang yang semakin berkurang.
javascript
Dan Kanze
sumber
sumber
Jawaban:
Saya berasumsi Anda menggunakan
splice
sesuatu seperti ini?for (var i = 0; i < arrayOfObjects.length; i++) { var obj = arrayOfObjects[i]; if (listToDelete.indexOf(obj.id) !== -1) { arrayOfObjects.splice(i, 1); } }
Yang perlu Anda lakukan untuk memperbaiki bug adalah pengurangan
i
untuk waktu berikutnya, lalu (dan mengulang ke belakang juga merupakan opsi):for (var i = 0; i < arrayOfObjects.length; i++) { var obj = arrayOfObjects[i]; if (listToDelete.indexOf(obj.id) !== -1) { arrayOfObjects.splice(i, 1); i--; } }
Untuk menghindari penghapusan waktu linier, Anda dapat menulis elemen array yang ingin Anda simpan di atas array:
var end = 0; for (var i = 0; i < arrayOfObjects.length; i++) { var obj = arrayOfObjects[i]; if (listToDelete.indexOf(obj.id) === -1) { arrayOfObjects[end++] = obj; } } arrayOfObjects.length = end;
dan untuk menghindari pencarian waktu linier dalam runtime modern, Anda dapat menggunakan kumpulan hash:
const setToDelete = new Set(listToDelete); let end = 0; for (let i = 0; i < arrayOfObjects.length; i++) { const obj = arrayOfObjects[i]; if (setToDelete.has(obj.id)) { arrayOfObjects[end++] = obj; } } arrayOfObjects.length = end;
yang bisa dibungkus dengan fungsi yang bagus:
const filterInPlace = (array, predicate) => { let end = 0; for (let i = 0; i < array.length; i++) { const obj = array[i]; if (predicate(obj)) { array[end++] = obj; } } array.length = end; }; const toDelete = new Set(['abc', 'efg']); const arrayOfObjects = [{id: 'abc', name: 'oh'}, {id: 'efg', name: 'em'}, {id: 'hij', name: 'ge'}]; filterInPlace(arrayOfObjects, obj => !toDelete.has(obj.id)); console.log(arrayOfObjects);
Jika Anda tidak perlu melakukannya di tempat, itu
Array#filter
:const toDelete = new Set(['abc', 'efg']); const newArray = arrayOfObjects.filter(obj => !toDelete.has(obj.id));
sumber
Anda dapat menghapus item dengan salah satu propertinya tanpa menggunakan lib pihak ketiga seperti ini:
var removeIndex = array.map(item => item.id) .indexOf("abc"); ~removeIndex && array.splice(removeIndex, 1);
sumber
Dengan lodash / garis bawah:
Jika Anda ingin memodifikasi array yang sudah ada, maka kita harus menggunakan splice . Berikut adalah cara yang sedikit lebih baik / mudah dibaca menggunakan findWhere dari garis bawah / lodash:
var items= [{id:'abc',name:'oh'}, // delete me {id:'efg',name:'em'}, {id:'hij',name:'ge'}]; items.splice(_.indexOf(items, _.findWhere(items, { id : "abc"})), 1);
Dengan ES5 atau lebih tinggi
( tanpa lodash / garis bawah )
Dengan ES5 dan seterusnya kami memiliki
findIndex
metode pada array, jadi mudah tanpa lodash / underscoreitems.splice(items.findIndex(function(i){ return i.id === "abc"; }), 1);
(ES5 didukung di hampir semua browser morden)
Tentang findIndex , dan kompatibilitas Browsernya
sumber
items.splice(items.findIndex(i => i.id === "abc"), 1)
findIndex berfungsi untuk browser modern:
var myArr = [{id:'a'},{id:'myid'},{id:'c'}]; var index = myArr.findIndex(function(o){ return o.id === 'myid'; }) if (index !== -1) myArr.splice(index, 1);
sumber
Untuk menghapus sebuah objek dengan idnya dalam larik yang diberikan;
const hero = [{'id' : 1, 'name' : 'hero1'}, {'id': 2, 'name' : 'hero2'}]; //remove hero1 const updatedHero = hero.filter(item => item.id !== 1);
sumber
Jika Anda hanya ingin menghapusnya dari array yang ada dan tidak membuat yang baru, coba:
var items = [{Id: 1},{Id: 2},{Id: 3}]; items.splice(_.indexOf(items, _.find(items, function (item) { return item.Id === 2; })), 1);
sumber
Ulangi secara terbalik dengan mengurangi
i
untuk menghindari masalah:for (var i = arrayOfObjects.length - 1; i >= 0; i--) { var obj = arrayOfObjects[i]; if (listToDelete.indexOf(obj.id) !== -1) { arrayOfObjects.splice(i, 1); } }
Atau gunakan
filter
:var newArray = arrayOfObjects.filter(function(obj) { return listToDelete.indexOf(obj.id) === -1; });
sumber
Lihat ini menggunakan Set dan filter ES6.
let result = arrayOfObjects.filter( el => (-1 == listToDelete.indexOf(el.id)) ); console.log(result);
Ini JsFiddle: https://jsfiddle.net/jsq0a0p1/1/
sumber
Sebagai alternatif, solusi yang lebih "fungsional", bekerja pada ECMAScript 5, Anda dapat menggunakan:
var listToDelete = ['abc', 'efg']; var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me {id:'efg',name:'em'}, // delete me {id:'hij',name:'ge'}]; // all that should remain arrayOfObjects.reduceRight(function(acc, obj, idx) { if (listToDelete.indexOf(obj.id) > -1) arrayOfObjects.splice(idx,1); }, 0); // initial value set to avoid issues with the first item and // when the array is empty. console.log(arrayOfObjects); [ { id: 'hij', name: 'ge' } ]
Menurut definisi 'Array.prototype.reduceRight' di ECMA-262 :
Jadi ini adalah penggunaan yang valid dari
reduceRight
.sumber
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me {id:'efg',name:'em'}, // delete me {id:'hij',name:'ge'}] // all that should remain
sesuai jawaban Anda akan seperti ini. ketika Anda mengklik beberapa objek tertentu, kirim indeks di param untuk fungsi delete me. Kode sederhana ini akan bekerja seperti pesona.
function deleteme(i){ if (i > -1) { arrayOfObjects.splice(i, 1); } }
sumber
dengan filter & indexOf
withLodash = _.filter(arrayOfObjects, (obj) => (listToDelete.indexOf(obj.id) === -1)); withoutLodash = arrayOfObjects.filter(obj => listToDelete.indexOf(obj.id) === -1);
dengan filter & termasuk
withLodash = _.filter(arrayOfObjects, (obj) => (!listToDelete.includes(obj.id))) withoutLodash = arrayOfObjects.filter(obj => !listToDelete.includes(obj.id));
sumber
Jika Anda menyukai parameter deskriptif pendek dan mandiri atau jika Anda tidak ingin menggunakan
splice
dan menggunakan filter langsung atau jika Anda hanyalah orang SQL seperti saya:function removeFromArrayOfHash(p_array_of_hash, p_key, p_value_to_remove){ return p_array_of_hash.filter((l_cur_row) => {return l_cur_row[p_key] != p_value_to_remove}); }
Dan contoh penggunaan:
l_test_arr = [ { post_id: 1, post_content: "Hey I am the first hash with id 1" }, { post_id: 2, post_content: "This is item 2" }, { post_id: 1, post_content: "And I am the second hash with id 1" }, { post_id: 3, post_content: "This is item 3" }, ]; l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 2); // gives both of the post_id 1 hashes and the post_id 3 l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 1); // gives only post_id 3 (since 1 was removed in previous line)
sumber
Anda bisa menggunakan
filter
. Metode ini selalu mengembalikan elemen jika kondisinya benar. Jadi jika Anda ingin menghapus dengan id Anda harus menyimpan semua elemen yang tidak cocok dengan id yang diberikan. Berikut ini contohnya:sumber