Bagaimana cara menggunakan metode include di lodash untuk memeriksa apakah suatu objek ada di dalam koleksi?

146

lodash memungkinkan saya memeriksa keanggotaan tipe data dasar dengan includes:

_.includes([1, 2, 3], 2)
> true

Tetapi yang berikut ini tidak berfungsi:

_.includes([{"a": 1}, {"b": 2}], {"b": 2})
> false

Ini membingungkan saya karena metode berikut yang mencari melalui koleksi tampaknya baik-baik saja:

_.where([{"a": 1}, {"b": 2}], {"b": 2})
> {"b": 2}
_.find([{"a": 1}, {"b": 2}], {"b": 2})
> {"b": 2}

Apa yang saya lakukan salah? Bagaimana cara saya memeriksa keanggotaan suatu objek dalam koleksi includes?

sunting: pertanyaan pada awalnya untuk untuk lodash versi 2.4.1, diperbarui untuk lodash 4.0.0

Conrad.Dean
sumber
7
_.containstelah dihapus di lodash v4 - gunakan _.includessaja
Billy Moon
@BillyMoon woops! ya Anda benar, lodash v4.0.0 (dirilis 2016-01-12) menghapus containsalias. Saya akan memperbarui ini
Conrad.Dean

Jawaban:

222

Metode includes(sebelumnya disebut containsdan include) membandingkan objek dengan referensi (atau lebih tepatnya, dengan ===). Karena dua objek literal {"b": 2}dalam contoh Anda mewakili contoh yang berbeda , mereka tidak sama. Memperhatikan:

({"b": 2} === {"b": 2})
> false

Namun, ini akan berhasil karena hanya ada satu contoh dari {"b": 2}:

var a = {"a": 1}, b = {"b": 2};
_.includes([a, b], b);
> true

Di sisi lain, metode where(usang dalam v4) dan findmetode membandingkan objek dengan properti mereka, sehingga mereka tidak memerlukan persamaan referensi. Sebagai alternatif includes, Anda mungkin ingin mencoba some(juga alias any):

_.some([{"a": 1}, {"b": 2}], {"b": 2})
> true
pswg
sumber
12

Melengkapi jawaban dengan p.s.w.g, berikut adalah tiga cara lain untuk mencapai ini menggunakan lodash 4.17.5, tanpa menggunakan _.includes() :

Katakanlah Anda ingin menambahkan objek entryke array objek numbers, hanya jika entrybelum ada.

let numbers = [
    { to: 1, from: 2 },
    { to: 3, from: 4 },
    { to: 5, from: 6 },
    { to: 7, from: 8 },
    { to: 1, from: 2 } // intentionally added duplicate
];

let entry = { to: 1, from: 2 };

/* 
 * 1. This will return the *index of the first* element that matches:
 */
_.findIndex(numbers, (o) => { return _.isMatch(o, entry) });
// output: 0


/* 
 * 2. This will return the entry that matches. Even if the entry exists
 *    multiple time, it is only returned once.
 */
_.find(numbers, (o) => { return _.isMatch(o, entry) });
// output: {to: 1, from: 2}


/* 
 * 3. This will return an array of objects containing all the matches.
 *    If an entry exists multiple times, if is returned multiple times.
 */
_.filter(numbers, _.matches(entry));
// output: [{to: 1, from: 2}, {to: 1, from: 2}]

Jika Anda ingin mengembalikan Boolean, dalam kasus pertama, Anda dapat memeriksa indeks yang dikembalikan:

_.findIndex(numbers, (o) => { return _.isMatch(o, entry) }) > -1;
// output: true
Mihai
sumber