web-dev-qa-db-fra.com

Comment utiliser la méthode includes dans lodash pour vérifier si un objet est dans la collection?

lodash me permet de vérifier l'appartenance aux types de données de base avec includes:

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

Mais ce qui suit ne fonctionne pas:

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

Cela me rend perplexe parce que les méthodes suivantes de recherche dans une collection semblent bien fonctionner:

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

Qu'est-ce que je fais mal? Comment vérifier l'appartenance d'un objet à une collection avec includes?

edit: question était à l'origine pour la version 2.4.1 de lodash, mis à jour pour la version 4.0.0 de lodash

119
Conrad.Dean

La méthode includes (anciennement appelée contains et include) compare les objets par référence (ou plus précisément avec ===). Parce que les deux littéraux d'objet de {"b": 2} dans votre exemple représentent des instances différentes , ils ne sont pas égaux. Remarquer:

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

Toutefois, cela fonctionnera car il n’existe qu’une seule instance de {"b": 2}:

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

D'autre part, les méthodes where (obsolète en v4) et find comparent les objets en fonction de leurs propriétés, de sorte qu'elles ne requièrent pas l'égalité de référence. Au lieu de includes, vous pouvez également essayer some (alias également comme any):

_.some([{"a": 1}, {"b": 2}], {"b": 2})
> true
183
p.s.w.g

Complétant la réponse par p.s.w.g, voici trois autres moyens d’atteindre cet objectif en utilisant lodash4.17.5, sans utiliser_.includes():

Supposons que vous souhaitiez ajouter l'objet entry à un tableau d'objets numbers, uniquement si entry n'existe pas encore.

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

Si vous voulez retourner un Boolean, dans le premier cas, vous pouvez vérifier l'index renvoyé:

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