Come posso usare il metodo include in lodash per verificare se un oggetto è nella collezione?


146

lodash mi permette di verificare l'appartenenza ai tipi di dati di base con includes:

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

Ma quanto segue non funziona:

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

Questo mi confonde perché i seguenti metodi che cercano in una raccolta sembrano andare bene:

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

Che cosa sto facendo di sbagliato? Come posso verificare l'appartenenza di un oggetto in una raccolta con includes?

modifica: la domanda era originariamente per la versione 2.4.1 di lodash, aggiornata per lodash 4.0.0


7
_.containsè stato rimosso in lodash v4 - utilizzare _.includesinvece
Billy Moon l'

@BillyMoon woops! sì, hai ragione, lodash v4.0.0 (rilasciato il 12-01-2016) rimuove l' containsalias. Lo aggiornerò
Conrad.Dean l'

Risposte:


222

Il metodo includes(precedentemente chiamato containse include) confronta gli oggetti per riferimento (o più precisamente, con ===). Poiché i due letterali oggetto di {"b": 2}nel tuo esempio rappresentano istanze diverse , non sono uguali. Avviso:

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

Tuttavia, funzionerà perché esiste solo un'istanza di {"b": 2}:

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

D'altra parte, i metodi where(deprecati in v4) e i findmetodi confrontano gli oggetti in base alle loro proprietà, quindi non richiedono l'uguaglianza di riferimento. In alternativa includes, potresti provare some(anche alias come any):

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

12

A completamento della risposta p.s.w.g, ecco altri tre modi per raggiungere questo obiettivo utilizzando lodash 4.17.5, senza utilizzare _.includes() :

Supponi di voler aggiungere un oggetto entrya un array di oggetti numbers, solo se entrynon esiste già.

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

Se si desidera restituire un Boolean, nel primo caso, è possibile controllare l'indice che viene restituito:

_.findIndex(numbers, (o) => { return _.isMatch(o, entry) }) > -1;
// output: true
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.