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
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
Complétant la réponse par p.s.w.g
, voici trois autres moyens d’atteindre cet objectif en utilisant lodash
4.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