Underscore: _.union ne fonctionne pas avec des tableaux d'objets

Créé le 2 oct. 2015  ·  32Commentaires  ·  Source: jashkenas/underscore

_.union produira toujours des doublons lors du passage de tableaux d'objets.

par exemple, _.union( [ { a:1 } ], [ { a:1 } ]) renverra [ { a:1 }, { a:1 } ]

Perversement, la fonction isEqual de underscore vous dira que les objets en question sont égaux. Peut-être pourrions-nous avoir un indicateur/une option qui dicte la comparaison d'égalité à utiliser, ou l'option de passer dans un comparateur ?

change

Commentaire le plus utile

Ce fil m'a inspiré pour ajouter _.intersectionWith , _.differenceWith , _.unionWith et _.uniqWith pour gérer la personnalisation de la comparaison dans mon propre code.

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

Tous les 32 commentaires

Je suis surpris qu'il n'accepte pas déjà la fonction de comparaison. :+1:

Il convient de souligner que cela s'applique à toutes les autres fonctions de calcul de tableau comme la différence, l'intersection, l'unique, etc.

Ce serait bien si la suite complète de fonctions de tableau pouvait être mise à jour pour permettre l'utilisation d'un comparateur d'égalité différent pour les objets.

Ne serait-il pas plus facile d'avoir une option qui compare l'égalité en fonction de la valeur du paramètre booléen qui pourrait être transmise à la fonction _.union() ? Si c'est vrai, il comparera automatiquement tous les objets de ce tableau.

Par exemple, _.union([1, 2, 3, 10, [{a:1}, {a:1}]], true) , produirait [1,2,3,10, {a:1}]

@amiral84 Non. Ce n'est pas lié. Si vous voulez ce comportement, composez union avec flatten.

@michaelficarra Alors ai-je raté l'intérêt de ce sujet ? :RÉ

@amiral84 Il semble que oui. La demande de fonctionnalité est expliquée de manière complète et succincte dans le premier commentaire.

le problème sous-jacent semble être dans _.uniq car _.union est simplement une fonction wrapper pour unique et flatten.

_.union = restArgs(function(arrays) {
  return _.uniq(flatten(arrays, true, true));
});

Ce fil m'a inspiré pour ajouter _.intersectionWith , _.differenceWith , _.unionWith et _.uniqWith pour gérer la personnalisation de la comparaison dans mon propre code.

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 quelque chose du genre _.isCollection pour déterminer si vous avez affaire à une collection. S'il s'agit d'une collection, les comparaisons doivent utiliser _.isEqual au lieu de === ce qui ne sert à rien dans le cas d'une collection.

@dperrymorrow

devrait utiliser _.isEqual au lieu de === ce qui ne sert à rien dans le cas d'une collection.

La commutation dynamique semble être une mauvaise idée. JS utilise des comparaisons === ou SameValueZero pour de nombreuses choses. S'il est nécessaire de sortir de ces comparaisons, quelque chose comme _.uniqWith ferait l'affaire.

Merci pour ce @jdalton , les fonctions _opWith que vous mentionnez sont absolument parfaites pour ce que j'essaie de réaliser. Une idée de quand ils seront disponibles via release ?

@jdalton bon point sur les comparaisons, mais n'utiliseriez-vous pas généralement une clé pour unique sur une collection plutôt que de forcer Underscore à détecter toute la différence entre les objets?

Est-ce que ce qui suit ne résoudrait pas la demande de @wilhen01 _(bien que plus détaillé que souhaité)_

_.chain([{ a: 1 }]).union( [{a: 1}]).unique('a').value();
//=> [{a: 1}]

Les éléments suivants ne résoudraient-ils pas la demande de @wilhen01 (bien que plus détaillé que souhaité)

_.uniq prend déjà en charge cela.

à droite, c'est mon point, le code ci-dessus fonctionne actuellement comme affiché.
ne pourrais-tu pas juste appeler uniq/unique avec une clé sur le résultat de l'union ?

@dperrymorrow Pensez juste un peu en dehors de cet exemple et ajoutez une autre propriété .

ok, gotcha, désolé... Je n'essaie pas d'être belliqueux, je voulais juste comprendre totalement le problème. J'adorerais soumettre une pull request sur la fonction _.uniqWith .

Pas de soucis, ce serait génial.

_.intersectionWith, _.differenceWith, _.unionWith et _.uniqWith

Ne serait-ce pas une API plus agréable de simplement permettre à la fonction de comparaison d'être facultativement passée en tant qu'argument final, au lieu de créer quatre nouvelles fonctions ?

@jashkenas

Ne serait-ce pas une API plus agréable de simplement permettre à la fonction de comparaison d'être facultativement passée en tant qu'argument final, au lieu de créer quatre nouvelles fonctions ?

Oui, cela pourrait être fait, mais il y a des complications car des méthodes comme _.uniq prennent déjà en charge le passage d'un itéré et sont fortement surchargées avec la prise en charge des indicateurs de recherche binaires/triés et des paramètres de contexte également. Cela signifierait introduire le reniflement d'arité qui semble trop intelligent pour cette situation. Cela compliquerait également les futurs efforts de modularisation car il regroupe de nombreuses fonctionnalités facultatives en un seul point lorsque les implémentations pourraient être simplifiées et divisées en méthodes distinctes.

Bon, un problème de conception totalement malheureux. Mais créer de nouvelles fonctions juste pour permettre un comparateur ne semble pas non plus être la bonne solution.

ok donc les paramètres de fonction de comparaison supplémentaires sont la voie à suivre ici alors?
Si c'est le cas, je peux mettre à jour ma pull request.

la seule partie délicate que je prévois est de rendre l'analyse des paramètres un peu plus velue comme @jdalton mentionné ci-dessus.

_.uniq = _.unique = function(array, isSorted, iteratee, context) {
  if (!_.isBoolean(isSorted)) {
    context = iteratee;
    iteratee = isSorted;
    isSorted = false;
  }
//...

Peut-être ajouter une vérification supplémentaire pour voir si isSorted _.isFunction puis le traiter comme le comparateur.

@jashkenas

Mais créer de nouvelles fonctions juste pour permettre un comparateur ne semble pas non plus être la bonne solution.

Cela peut être la meilleure option pour une mauvaise situation. J'ai récemment décidé de séparer les fonctionnalités surchargées et j'ai été assez satisfait du résultat. Bien qu'il augmente la surface de l'API, il permet des implémentations plus simples et un regroupement de méthodes à thème similaire comme maxBy , uniqBy , pickBy , ou uniqWith , unionWith , zipWith , ou sortedIndexBy , sortedIndexOf , sortedUniq . Dans le cas de uniq j'utilise toujours une fonction de base partagée pour le moment.

ont mis à jour cette pull request #2368 merci.

Je suis :+1: pour uniqBy ou uniqWith . Je serais complètement contre la surcharge de uniq (comme le #2368 est actuellement proposé)

:+1: @megawac , uniqBy .

Fwiw lodash utilisera uniqBy comme forme de fractionnement de _.uniq(array, iteratee) et _.uniqWith comme forme pour permettre la personnalisation du comparateur.

Ouais, à la réflexion, uniqWith est un meilleur nom

dois-je alors extraire la demande sur Lodash avec la méthode séparée ?
Je pensais que les deux projets fusionnaient, je me trompe ?

@dperrymorrow

devrais-je tirer la demande sur Lodash avec la méthode séparée alors

Pas besoin, ils sont déjà dans la branche master de lodash.

Je pensais que les deux projets fusionnaient, je me trompe ?

Pas encore. Lodash v4 met cependant à l'épreuve certaines des idées de la fusion.

@jdalton Pouvez-vous s'il vous plaît élaborer un peu plus sur la mise en œuvre de _.uniqWith avec d'autres itérés.

@Pavnii
Sûr. Vous pouvez consulter lodash/npm/_baseUniq .
Si un comparator est passé, il utilise l'assistant arrayIncludesWith pour effectuer la vérification au lieu de arrayIncludes (le soulignement contains ).

@jdalton Cela m'aide.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

jdalton picture jdalton  ·  4Commentaires

marcalj picture marcalj  ·  5Commentaires

clouddueling picture clouddueling  ·  3Commentaires

zackschuster picture zackschuster  ·  5Commentaires

umarfarooq125 picture umarfarooq125  ·  8Commentaires