lodash permite-me verificar se os tipos de dados básicos são membros com `inclui':
_.includes([1, 2, 3], 2)
> true
Mas o seguinte não't funciona:
_.includes([{"a": 1}, {"b": 2}], {"b": 2})
> false
Isto confunde-me porque os seguintes métodos que pesquisam através de uma colecção parecem ser muito bons:
_.where([{"a": 1}, {"b": 2}], {"b": 2})
> {"b": 2}
_.find([{"a": 1}, {"b": 2}], {"b": 2})
> {"b": 2}
O que é que estou a fazer mal? Como posso verificar se sou membro de um objecto de uma colecção com `inclui' ?
editar: pergunta foi originalmente para lodash versão 2.4.1, actualizada para lodash 4.0.0
O método -inclui (anteriormente chamado contém' e
inclui') compara objectos por referência (ou mais precisamente, com ===``). Porque os dois objectos literais de
{"b": 2}` no seu exemplo representam diferentes instâncias, não são iguais. Atenção:
({"b": 2} === {"b": 2})
> false
Contudo, isto funcionará porque existe apenas uma instância de `{"b": 2}``:
var a = {"a": 1}, b = {"b": 2};
_.includes([a, b], b);
> true
Por outro lado, os métodos where'(depreciado em v4) e find' comparam objectos pelas suas propriedades, pelo que não'não requerem igualdade de referência. Como alternativa ao inclui
, talvez queira tentar alguns` (também conhecido como any
):
_.some([{"a": 1}, {"b": 2}], {"b": 2})
> true
Complementando a resposta por p.s.w.g
, aqui estão três outras formas de conseguir isto utilizando lodash
4.17.5
, sem utilizar _.includes()
:
Digamos que pretende adicionar "entrada" a um conjunto de objectos "números", apenas se "entrada" ainda não existir.
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 quiser devolver um Booleano
, no primeiro caso, pode verificar o índice que está a ser devolvido:
_.findIndex(numbers, (o) => { return _.isMatch(o, entry) }) > -1;
// output: true