lodash me permite comprobar la pertenencia de los tipos de datos básicos con includes
:
_.includes([1, 2, 3], 2)
> true
Pero lo siguiente no funciona:
_.includes([{"a": 1}, {"b": 2}], {"b": 2})
> false
Esto me confunde porque los siguientes métodos que buscan a través de una colección parecen hacerlo bien:
_.where([{"a": 1}, {"b": 2}], {"b": 2})
> {"b": 2}
_.find([{"a": 1}, {"b": 2}], {"b": 2})
> {"b": 2}
¿Qué estoy haciendo mal? ¿Cómo puedo comprobar la pertenencia de un objeto a una colección con includes
?
editar: la pregunta era originalmente para la versión 2.4.1 de lodash, actualizada para lodash 4.0.0
El método includes
(antes llamado contains
e include
) compara objetos por referencia (o más exactamente, con ===
). Como los dos literales de objeto de {"b": 2}
en tu ejemplo representan instancias diferentes, no son iguales. Fíjese:
({"b": 2} === {"b": 2})
> false
Sin embargo, esto funcionará porque sólo hay una instancia de {"b": 2}
:
var a = {"a": 1}, b = {"b": 2};
_.includes([a, b], b);
> true
Por otro lado, los métodos where
(obsoleto en v4) y find
comparan objetos por sus propiedades, por lo que no requieren igualdad de referencias. Como alternativa a includes
, puede probar con some
(también llamado any
):
_.some([{"a": 1}, {"b": 2}], {"b": 2})
> true
Complementando la respuesta de p.s.w.g
, aquí hay otras tres maneras de lograr esto usando lodash
4.17.5
, sin usar _.includes()
:
Digamos que quieres añadir el objeto entry
a un array de objetos numbers
, sólo si entry
no existe ya.
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 quieres devolver un Boolean
, en el primer caso, puedes comprobar el índice que se devuelve:
_.findIndex(numbers, (o) => { return _.isMatch(o, entry) }) > -1;
// output: true