886 votes

Comment supprimer tous les doublons d'un tableau d'objets ?

J'ai un objet qui contient un tableau d'objets.

obj = {};

obj.arr = new Array();

obj.arr.push({place:"here",name:"stuff"});
obj.arr.push({place:"there",name:"morestuff"});
obj.arr.push({place:"there",name:"morestuff"});

Je me demande quelle est la meilleure méthode pour supprimer les objets en double d'un tableau. Par exemple, obj.arr deviendrait...

{place:"here",name:"stuff"},
{place:"there",name:"morestuff"}

0 votes

Voulez-vous dire comment empêcher qu'une table de hachage/un objet avec tous les mêmes paramètres soit ajouté à un tableau ?

9 votes

Mathew -> S'il est plus simple d'empêcher un objet en double d'être ajouté au tableau en premier lieu, au lieu de le filtrer plus tard, oui, ce serait bien aussi.

18 votes

Je suis toujours surpris de voir comment les gens nomment leurs variables. Parfois, je pense qu'ils veulent vraiment rendre les choses inutilement compliquées. La prochaine étape sera aaaaa.aaaa.push(...) :)

1voto

Nina Scholz Points 17120

Il s'agit d'une approche à boucle unique avec une Set et quelques fermetures pour empêcher l'utilisation de variables déclarées en dehors des déclarations de fonctions et pour obtenir une apparence courte.

const
    array = [{ place: "here", name: "stuff", n: 1 }, { place: "there", name: "morestuff", n: 2 }, { place: "there", name: "morestuff", n: 3 }],
    keys = ['place', 'name'],
    unique = array.filter(
        (s => o => (v => !s.has(v) && s.add(v))(keys.map(k => o[k]).join('|')))
        (new Set)
    );

console.log(unique);

.as-console-wrapper { max-height: 100% !important; top: 0; }

0voto

HD.. Points 869

Voici une autre technique pour trouver le nombre de doublons et les supprimer facilement de votre objet de données. "dupsCount" est le nombre de fichiers en double. Triez d'abord vos données puis supprimez-les. Cela vous permettra de supprimer les doublons plus rapidement.

  dataArray.sort(function (a, b) {
            var textA = a.name.toUpperCase();
            var textB = b.name.toUpperCase();
            return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
        });
        for (var i = 0; i < dataArray.length - 1; ) {
            if (dataArray[i].name == dataArray[i + 1].name) {
                dupsCount++;
                dataArray.splice(i, 1);
            } else {
                i++;
            }
        }

0voto

ykay Points 1919

Si vous avez besoin d'un tableau unique basé sur plusieurs propriétés de l'objet, vous pouvez le faire avec map et en combinant les propriétés de l'objet.

    var hash = array.map(function(element){
        var string = ''
        for (var key in element){
            string += element[key]
        }
        return string
    })
    array = array.filter(function(element, index){
        var string = ''
        for (var key in element){
            string += element[key]
        }
        return hash.indexOf(string) == index
    })

0voto

aSoler Points 130

Générique pour tout tableau d'objets :

/**
* Remove duplicated values without losing information
*/
const removeValues = (items, key) => {
  let tmp = {};

  items.forEach(item => {
    tmp[item[key]] = (!tmp[item[key]]) ? item : Object.assign(tmp[item[key]], item);
  });
  items = [];
  Object.keys(tmp).forEach(key => items.push(tmp[key]));

  return items;
}

J'espère que cela pourra être utile à tous.

0voto

Keammoort Points 2812

Une autre façon serait d'utiliser la fonction reduce et d'avoir un nouveau tableau pour être l'accumulateur. S'il y a déjà un thing avec le même nom dans le tableau de l'accumulateur, alors ne l'ajoutez pas.

let list = things.thing;
list = list.reduce((accumulator, thing) => {
    if (!accumulator.filter((duplicate) => thing.name === duplicate.name)[0]) {
        accumulator.push(thing);
    }
    return accumulator;
}, []);
thing.things = list;

J'ajoute cette réponse, car je n'ai pas trouvé de solution es6 agréable et lisible (j'utilise babel pour gérer les fonctions de flèches) qui soit compatible avec Internet Explorer 11. Le problème est que IE11 n'a pas Map.values() o Set.values() sans polyfill. Pour la même raison, j'ai utilisé filter()[0] pour obtenir le premier élément au lieu de find() .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X