_.union sempre produzirá duplicatas quando forem passados arrays de objetos.
por exemplo, _.union( [ { a:1 } ], [ { a:1 } ])
retornará [ { a:1 }, { a:1 } ]
Perversamente, a função isEqual do próprio sublinhado informará que os objetos em questão são iguais. Talvez pudéssemos ter um sinalizador / opção que dita a comparação de igualdade a ser usada, ou a opção de passar um comparador?
Estou surpreso que ainda não aceite a função de comparação. : +1:
É importante ressaltar que isso se aplica a todas as outras funções de computação de array, como diferença, interseção, único, etc.
Seria bom se o conjunto completo de funções de matriz pudesse ser atualizado para permitir o uso de um comparador de igualdade diferente para objetos.
Não seria mais fácil se tivéssemos uma opção que compara a igualdade com base no valor do parâmetro booleano que pode ser passado para a função _.union ()? Se for verdade, ele irá comparar automaticamente todos os objetos nessa matriz.
Por exemplo, _.union([1, 2, 3, 10, [{a:1}, {a:1}]], true)
, produziria [1,2,3,10, {a:1}]
@ amiral84 Não. Isso não está relacionado. Se você deseja esse comportamento, componha união com achatar.
@michaelficarra Então eu perdi o objetivo desse tópico? : D
@ amiral84 Parece que sim. A solicitação de recurso é explicada completa e sucintamente no primeiro comentário.
o problema subjacente parece estar em _.uniq
pois _.union
é meramente uma função de empacotamento para exclusivo e nivelado.
_.union = restArgs(function(arrays) {
return _.uniq(flatten(arrays, true, true));
});
Este tópico me inspirou a adicionar _.intersectionWith
, _.differenceWith
, _.unionWith
e _.uniqWith
para lidar com a personalização de comparação em meu próprio código.
var array = [ { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 3 }, { 'a': 1, 'b': 2 } ];
_.uniqWith(array, _.isEqual);
// => [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 3 }]
ou algo parecido com _.isCollection
para determinar se você está lidando com uma coleção. Se estiver lidando com uma coleção, então as comparações devem usar _.isEqual
vez de ===
que não adianta no caso de uma coleção.
@dperrymorrow
deve usar
_.isEqual
vez de===
que não adianta no caso de uma coleção.
A comutação dinâmica parece uma má ideia. JS usa ===
ou SameValueZero
comparações para muitas coisas. Se houver necessidade de ir além dessas comparações, algo como _.uniqWith
faria.
Obrigado por este @jdalton , as funções _opWith que você mencionou são absolutamente perfeitas para o que estou tentando alcançar. Alguma ideia de quando eles estarão disponíveis via lançamento?
@jdalton é uma boa observação sobre as comparações, mas você normalmente não usaria uma chave de exclusividade em uma coleção em vez de forçar o sublinhado para detectar toda a diferença entre os objetos?
O seguinte não resolveria a solicitação de @ wilhen01 _ (embora mais prolixo do que o desejado) _
_.chain([{ a: 1 }]).union( [{a: 1}]).unique('a').value();
//=> [{a: 1}]
O seguinte não resolveria a solicitação de @ wilhen01 (embora mais prolixo do que o desejado)
_.uniq
já suporta isso.
certo, esse é o meu ponto, o código acima funciona conforme postado.
você não poderia simplesmente chamar uniq / unique com uma chave no resultado da união?
@dperrymorrow Pense um pouco fora desse exemplo e adicione outra propriedade .
ok, entendi, desculpe ... Não estou tentando ser beligerante, só queria entender totalmente o problema. Eu adoraria enviar uma solicitação de pull na função _.uniqWith
.
Não se preocupe, isso seria demais.
_.intersectionWith, _.differenceWith, _.unionWith e _.uniqWith
Não seria uma API melhor permitir apenas que a função de comparação fosse opcionalmente passada como o argumento final, em vez de cunhar quatro novas funções?
@jashkenas
Não seria uma API melhor permitir apenas que a função de comparação fosse opcionalmente passada como o argumento final, em vez de cunhar quatro novas funções?
Sim, isso poderia ser feito, mas há complicações porque métodos como _.uniq
já suportam a passagem de um iteratee e estão muito sobrecarregados com suporte para sinalizadores de pesquisa binários / classificados e parâmetros de contexto também. Isso significaria introduzir uma cheirada de aridade, que parece muito inteligente para esta situação. Isso também complicaria os esforços de modularização futuros porque agrupa muitas funcionalidades opcionais em um único ponto, quando as implementações poderiam ser simplificadas e divididas em métodos separados.
Certo, um problema de design totalmente infeliz. Mas criar novas funções apenas para permitir um comparador também não parece a solução certa.
ok, então, parâmetros de função de comparação adicionais são o caminho a percorrer aqui?
Nesse caso, posso atualizar minha solicitação de pull.
a única parte complicada que prevejo é tornar a análise de parâmetro um pouco mais complicada, como @jdalton mencionado acima.
_.uniq = _.unique = function(array, isSorted, iteratee, context) {
if (!_.isBoolean(isSorted)) {
context = iteratee;
iteratee = isSorted;
isSorted = false;
}
//...
Talvez adicionando uma verificação adicional para ver se isSorted _.isFunction
e trate-o como o comparador.
@jashkenas
Mas criar novas funções apenas para permitir um comparador também não parece a solução certa.
Pode ser a melhor opção para uma situação ruim. Eu comecei a dividir funcionalidades sobrecarregadas recentemente e estou muito feliz com o resultado. Embora aumente a superfície da API, permite implementações mais simples e agrupamento de métodos com temas semelhantes, como maxBy
, uniqBy
, pickBy
ou uniqWith
, unionWith
, zipWith
, ou sortedIndexBy
, sortedIndexOf
, sortedUniq
. No caso de uniq
embora eu ainda use uma função de base compartilhada no momento.
atualizei esta solicitação pull # 2368, obrigado.
Eu sou: +1: para uniqBy
ou uniqWith
. Eu seria totalmente contra sobrecarregar uniq
ainda mais (como # 2368 é proposto atualmente)
: +1: @megawac , uniqBy
.
Fwiw Lodash usará uniqBy
como a forma de divisão de _.uniq(array, iteratee)
e _.uniqWith
como a forma para permitir a personalização do comparador.
Sim, pensando bem, uniqWith
é um nome melhor
devo puxar a solicitação no Lodash com o método separado então?
Pensei que os dois projetos se fundissem, estou enganado?
@dperrymorrow
devo puxar o pedido no Lodash com o método separado, então
Não há necessidade, eles já estão no branch master de borda de Lodash.
Pensei que os dois projetos se fundissem, estou enganado?
Ainda não. O Lodash v4 prova algumas das ideias da fusão, no entanto.
@jdalton Você pode elaborar um liitle mais sobre a implementação de _.uniqWith
com outro iteratee.
@Pavnii
Certo. Você pode verificar lodash / npm / _baseUniq .
Se um comparator
for passado, ele usa arrayIncludesWith
auxiliar para fazer a verificação em vez de arrayIncludes
(sublinhado contains
).
@jdalton Isso me ajuda.
Comentários muito úteis
Este tópico me inspirou a adicionar
_.intersectionWith
,_.differenceWith
,_.unionWith
e_.uniqWith
para lidar com a personalização de comparação em meu próprio código.