Comment puis-je utiliser Set () dans des objets? J'ai lu la documentation, cela fonctionne avec des valeurs dans un tableau, mais avec des objets ça ne marche pas. Pourquoi? Je veux éviter les éléments en double qui ont exactement les mêmes valeurs.

let nameList_one = [{ name: 'harry', id: 1 }, { name: 'john', id: 2 }, { 'name': 'trevor', id: 3  }]
let nameList_two = [{ name: 'harry', id: 1  }, { name: 'ron', id: 4  }, { name: 'jackson', id: 5  }]

let fullNameList = [...nameList_one , ...nameList_two ]

let filteredList = [...new Set(fullNameList)] // the output is the merge of two array, duplicating "harry".

Sortie:

[{nom: 'harry', id: 1}, {name: 'john', id: 2}, {'name': 'trevor', id: 3}, {name: 'harry', id: 1} , {nom: 'ron', id: 4}, {nom: 'jackson', id: 5}]

Résultat attendu:

[{nom: 'harry', id: 1}, {nom: 'john', id: 2}, {'name': 'trevor', id: 3}, {name: 'ron', id: 4} , {nom: 'jackson', id: 5}]

Merci!!

5
Johnson 13 avril 2018 à 18:16

3 réponses

Meilleure réponse

Cela ne fonctionne pas avec les objets car ce ne sont pas les mêmes objets:

{ name: 'harry', id: 1 } !== { name: 'harry', id: 1 }

Une façon qui peut fonctionner est:

let filteredList = [...new Set(fullNameList.map(JSON.stringify))].map(JSON.parse);

Il ne peut pas être recommandé, car il utilise la sérialisation là où elle n'est pas nécessaire. La sérialisation détruira les instances d'objets qui ne peuvent pas être sérialisées, ignorera les propriétés non énumérables et ne gérera pas les références circulaires. Les objets dont l'ordre des propriétés est différent ne seront pas supprimés en tant que doublons. Leurs propriétés doivent être triées en premier. En cas d'objets imbriqués, les clés doivent être triées de manière récursive. Cela rend cette approche peu pratique.

Si les objets sont identifiés par un ou plusieurs champs, Map avec des champs sérialisés comme clés de carte peut être utilisé:

let filteredList = [
  ...new Map(fullNameList.map(obj => [`${obj.id}:${obj.name}`, obj]))
  .values()
];
3
Estus Flask 27 févr. 2020 à 10:00

Une bonne façon de procéder est de sous-classer Set.

class UniqueNameSet extends Set {
    constructor(values) {
        super(values);

        const names = [];
        for (let value of this) {
            if (names.includes(value.name)) {
                this.delete(value);
            } else {
                names.push(value.name);
            }
        }
    }
}

Cela vous donne toutes les autres méthodes / propriétés de Set, mais ajoute les fonctionnalités supplémentaires que vous recherchez.

2
lonesomeday 13 avril 2018 à 16:35

Chaque objet est un pointeur vers une adresse mémoire, donc même si les deux objets ont les mêmes propriétés, ils ne seront pas égaux. Une façon de le faire serait d'utiliser JSON.stringify et de copare l'objet stringifié.

1
Douglas 13 avril 2018 à 16:36