Jak używać metody include w lodash, aby sprawdzić, czy obiekt znajduje się w kolekcji?

146

lodash pozwala mi sprawdzić przynależność do podstawowych typów danych z includes:

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

Ale to nie działa:

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

To mnie dezorientuje, ponieważ następujące metody przeszukiwania kolekcji wydają się dobrze działać:

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

Co ja robię źle? Jak sprawdzić przynależność obiektu do kolekcji za pomocą includes?

edycja: pytanie było pierwotnie dla lodash w wersji 2.4.1, zaktualizowane dla lodash 4.0.0

Conrad Dean
źródło
7
_.containszostał usunięty w lodash v4 - użyj _.includeszamiast tego
Billy Moon,
@BillyMoon woops! tak, masz rację, lodash v4.0.0 (wydany 12.01.2016) usuwa containsalias. Zaktualizuję to
Conrad.Dean

Odpowiedzi:

222

Metoda includes(wcześniej nazywana containsi include) porównuje obiekty przez odniesienie (a dokładniej z ===). Ponieważ dwa literały obiektu {"b": 2}w przykładzie reprezentują różne wystąpienia, nie są równe. Ogłoszenie:

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

Jednak to zadziała, ponieważ istnieje tylko jedno wystąpienie {"b": 2}:

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

Z drugiej strony where(przestarzałe w wersji 4) i findmetody porównują obiekty według ich właściwości, więc nie wymagają równości odwołań. Alternatywnie includesmożesz spróbować some(również z aliasem jako any):

_.some([{"a": 1}, {"b": 2}], {"b": 2})
> true
pswg
źródło
12

Uzupełniając odpowiedź p.s.w.g, oto trzy inne sposoby osiągnięcia tego za pomocą lodash 4.17.5, bez użycia _.includes() :

Powiedzmy, że chcesz dodać obiekt entrydo tablicy obiektów numbers, tylko jeśli jeszcze entrynie istnieje.

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}]

Jeśli chcesz zwrócić a Boolean, w pierwszym przypadku możesz sprawdzić zwracany indeks:

_.findIndex(numbers, (o) => { return _.isMatch(o, entry) }) > -1;
// output: true
Mihai
źródło