Bagaimana saya bisa menghapus elemen dari daftar, dengan lodash?


165

Saya memiliki objek yang terlihat seperti ini:

var obj = {
    "objectiveDetailId": 285,
    "objectiveId": 29,
    "number": 1,
    "text": "x",
    "subTopics": [{
        "subTopicId": 1,
        "number": 1
    }, {
        "subTopicId": 2,
        "number": 32
    }, {
        "subTopicId": 3,
        "number": 22
    }]
}
var stToDelete = 2;

saya sudah lodash menginstal aplikasi saya untuk hal-hal lain. Apakah ada cara efisien untuk digunakan lodashuntuk menghapus entri: {"subTopicId":2, "number":32}dari objobjek?

Atau adakah cara javascript untuk melakukan ini?


1
Anda cukup menggunakan splice( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) untuk menghapus item dari daftar
z33m

1
Mengubah judul karena menghapus 4 dari larik [1,4,5] tidak dapat dilakukan dengan cara ini. Ya, saya mengerti bahwa array dapat diimplementasikan dari hash / objek dan mungkin ada, tetapi ada perbedaan yang halus di kedua. Untuk menghapus dari array yang akan Anda gunakan result = _.pull(arr, value) Ini akan menghapus semua nilai yang cocok dari daftar.
boatcoder

Jawaban:


247

Seperti yang ditunjukkan lyyons dalam komentar, cara yang lebih idiomatis dan mudah untuk melakukan ini adalah menggunakan _.remove, seperti ini

_.remove(obj.subTopics, {
    subTopicId: stToDelete
});

Selain itu, Anda dapat melewati fungsi predikat yang hasilnya akan digunakan untuk menentukan apakah elemen saat ini harus dihapus atau tidak.

_.remove(obj.subTopics, function(currentObject) {
    return currentObject.subTopicId === stToDelete;
});

Atau, Anda dapat membuat array baru dengan memfilter yang lama dengan _.filterdan menetapkannya ke objek yang sama, seperti ini

obj.subTopics = _.filter(obj.subTopics, function(currentObject) {
    return currentObject.subTopicId !== stToDelete;
});

Atau

obj.subTopics = _.filter(obj.subTopics, {subTopicId: stToKeep});

3
Alasan mengapa jawaban ini mengganggu adalah karena Anda dapat menggunakan fungsi predikat , yang persis seperti yang saya cari. Menghapus sebuah elemen itu sepele jika Anda tahu indeksnya, tetapi bagaimana kalau Anda tidak tahu indeksnya?
random_user_name

3
Mungkin perlu disebutkan _filter jika Anda tidak ingin mengubah array asli ....
random_user_name

@cale_b Terima kasih :-) Memperbarui jawabannya dengan _.filterversi.
theouroureye

7
@thefourtheye _.filter mengembalikan elemen jika predikatnya benar. Implementasi Anda akan mengembalikan semua elemen yang tidak diinginkan dan bukan yang ingin Anda pertahankan
Xeltor

5
@thefourtheye, Anda harus menggunakan _.rejectalih-alih _.filtermenggunakan predikat yang sama. Periksa jawaban saya untuk lebih jelasnya!
Xeltor

29

Cukup gunakan vanilla JS. Anda dapat menggunakan spliceuntuk menghapus elemen:

obj.subTopics.splice(1, 1);

Demo


3
tanya penggunaIs there an efficient way to use _lodash to delete
semirturgay

7
@Andy Anda benar, tetapi bagaimana jika indeksnya belum diketahui?
theouroureye

3
splice () adalah pendekatan terbaik jika Anda ingin array Anda dimutasi. Jika Anda menggunakan hapus maka itu akan mengembalikan array baru dan ini harus dipindahkan.
omarjebari

Jika Anda ingin menghapus item dari array dengan indeksnya di array (jelas, Anda memiliki indeks ini jika Anda ingin melakukan tindakan hapus dengan cara ini), maka menggunakan metode splice adalah cara yang paling efisien (dan mudah) untuk melakukannya. Tidak perlu membandingkan apa pun dan membuat kode lebih rumit dan rentan terhadap bug dan kesalahan ...
TheCuBeMan

26

Anda bisa melakukannya dengan _pull.

_.pull(obj["subTopics"] , {"subTopicId":2, "number":32});

periksa referensi


7
Per dokumen, _.pullgunakan kesetaraan ketat untuk perbandingan, yaitu === . Dua objek polos yang berbeda tidak akan pernah dibandingkan sebagai sama dengan ===(atau oleh ==karena itu). Dengan demikian kode Anda di atas tidak akan pernah menghapus elemen apa pun dari array.
Mark Amery

1
Namun, itulah satu-satunya yang bekerja dengan string dalam array. _.removehanya menyiram array.
Yauheni Prakopchyk

3
Saya masih berpikir ini adalah jawaban yang tepat. JS .filter menghapus semua elemen yang cocok, JS .splice mengharuskan saya mengetahui indeksnya, _.hapus iterate atas semua elemen array sehingga kurang efisien. _.pull persis seperti yang saya inginkan: _.pull (array, itemToRemove).
Yehuda Gabriel Himango

21

Anda sekarang dapat menggunakan _.reject yang memungkinkan Anda untuk memfilter berdasarkan apa yang perlu Anda singkirkan, alih-alih apa yang perlu Anda pertahankan.

tidak seperti _.pullatau _.removeyang hanya bekerja pada array, ._rejectbekerja pada semua Collection

obj.subTopics = _.reject(obj.subTopics, (o) => {
  return o.number >= 32;
});

2

Ada empat cara untuk melakukan ini seperti yang saya tahu

const array = [{id:1,name:'Jim'},{id:2,name:'Parker'}];
const toDelete = 1;

Pertama:

_.reject(array, {id:toDelete})

Yang kedua adalah:

_.remove(array, {id:toDelete})

Dengan cara ini array akan dimutasi.

Yang ketiga adalah:

_.differenceBy(array,[{id:toDelete}],'id')
// If you can get remove item 
// _.differenceWith(array,[removeItem])

Yang terakhir adalah:

_.filter(array,({id})=>id!==toDelete)

Saya belajar lodash

Jawab untuk membuat catatan, sehingga saya bisa menemukannya nanti.


Saya mencarireject
Sampgun

2

Selain jawaban @thefourtheye, gunakan predikat alih-alih fungsi anonim tradisional:

  _.remove(obj.subTopics, (currentObject) => {
        return currentObject.subTopicId === stToDelete;
    });

ATAU

obj.subTopics = _.filter(obj.subTopics, (currentObject) => {
    return currentObject.subTopicId !== stToDelete;
});

1

naskah dan naskah

const clearSubTopics = _.filter(obj.subTopics, topic => (!_.isEqual(topic.subTopicId, 2)));
console.log(clearSubTopics);

0

Berikut adalah fungsi lodash sederhana dengan array dan menghapusnya dengan nomor indeks.

index_tobe_delete = 1

fruit = [{a: "apple"}, {b: "banana"}, {c: "choco"}]
_.filter(fruit, (value, key)=> {
return (key !== index_tobe_delete)
})
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.