J'ai un tableau d'objets avec des doublons et j'essaie d'obtenir une liste unique, où l'unicité est définie par un sous-ensemble des propriétés de l'objet. Par exemple,
{a:"1",b:"1",c:"2"}
Et je veux ignorer c
dans la comparaison d'unicité.
Je peux faire quelque chose comme
_.uniq(myArray,function(element) { return element.a + "_" + element+b});
J'espérais pouvoir faire
_.uniq(myArray,function(element) { return {a:element.a, b:element.b} });
Mais ça ne marche pas. Est-ce que je peux faire quelque chose de ce genre ou dois-je créer une représentation comparable de l'objet si je compare plusieurs propriétés?
Malheureusement, il ne semble pas y avoir de solution simple. À moins d’écrire votre propre fonction pour cela, vous devrez renvoyer quelque chose qui peut être comparé directement pour l’égalité (comme dans votre premier exemple).
Une méthode serait de simplement .join()
les propriétés dont vous avez besoin:
_.uniqBy(myArray, function(elem) { return [elem.a, elem.b].join(); });
Vous pouvez également utiliser _.pick
ou _.omit
pour supprimer tout ce dont vous n’avez pas besoin. À partir de là, vous pouvez utiliser _.values
avec une .join()
, ou même simplement JSON.stringify
:
_.uniqBy(myArray, function(elem) {
return JSON.stringify(_.pick(elem, ['a', 'b']));
});
Gardez à l'esprit que les objets ne sont pas déterministes en ce qui concerne l'ordre des propriétés, vous pouvez donc vous en tenir à l'approche de tableau explicite.
P.S. Remplacez uniqBy
par uniq
pour Lodash <4
Je pense que l'approche join () est toujours la plus simple. En dépit des préoccupations exprimées dans la solution précédente, je pense que le choix du séparateur approprié est la solution pour éviter les pièges identifiés (avec des ensembles de valeurs différents renvoyant la même valeur jointe). N'oubliez pas que le séparateur ne doit pas nécessairement être un seul caractère. Il peut s'agir de n'importe quelle chaîne qui, selon vous, n'apparaîtra pas naturellement dans les données. Je fais cela tout le temps et j'aime bien utiliser '~! $ ~' Comme séparateur. Il peut également inclure des caractères spéciaux tels que\t\r\n etc.
Si les données contenues sont vraiment aussi imprévisibles, peut-être connaissez-vous la longueur maximale et pourriez-vous simplement ajouter à chaque élément une longueur maximale avant de les associer.
Les réponses @voithos et @Danail sont un indice. J'ai résolu ce problème en ajoutant une clé unique sur les objets de mon tableau.
Données de départ
const animalArray = [
{ a: 4, b: 'cat', d: 'generic' },
{ a: 5, b: 'cat', d: 'generic' },
{ a: 4, b: 'dog', d: 'generic' },
{ a: 4, b: 'cat', d: 'generic' },
];
Dans l'exemple ci-dessus, je veux que le tableau soit unique par a
et b
, mais j'ai deux objets qui ont a: 4
et b: 'cat'
. En combinant a + b dans une chaîne, je peux obtenir une clé unique à vérifier.
{ a: 4, b: 'cat', d: 'generic', id: `${a}-${b}` }. // id is now '4-cat'
Remarque: Vous devez évidemment mapper les données ou le faire lors de la création de l'objet car vous ne pouvez pas référencer les propriétés d'un objet dans le même objet.
Maintenant, la comparaison est simple ...
_.uniqBy(animalArray, 'id');
Le tableau résultant aura une longueur de 3, il aura supprimé le dernier duplicata.