Question Supprimer les doublons d'un tableau d'objets en JavaScript


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

things = new Object();

things.thing = new Array();

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

Je me demande quelle est la meilleure méthode pour supprimer les objets en double d'un tableau. Ainsi, par exemple, les choses deviendraient ...

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

173
2018-02-08 00:40


origine


Réponses:


Voyons voir ... un primitif serait:

var obj = {};

for ( var i=0, len=things.thing.length; i < len; i++ )
    obj[things.thing[i]['place']] = things.thing[i];

things.thing = new Array();
for ( var key in obj )
    things.thing.push(obj[key]);

Ok, je pense que ça devrait faire l'affaire. Check it out, Travis.

MODIFIER
Editer le code pour référencer correctement le place (ancien id) propriété .


103
2018-02-08 00:47



Que diriez-vous de es6 la magie?

things.thing = things.thing.filter((thing, index, self) =>
  index === self.findIndex((t) => (
    t.place === thing.place && t.name === thing.name
  ))
)

URL de référence

Pour les frontaux, cela pourrait être un peu tôt pour mettre en œuvre car beaucoup de navigateurs utilisés ne supportent toujours pas les fonctionnalités es6


186
2018-04-20 13:04



Si vous pouvez utiliser des bibliothèques Javascript telles que souligner ou lodash, je recommande de jeter un oeil à _.uniq fonction dans leurs bibliothèques. De lodash:

_.uniq(array, [isSorted=false], [callback=_.identity], [thisArg])

Fondamentalement, vous passez dans le tableau qui est ici un littéral d'objet et vous passez dans l'attribut avec lequel vous voulez supprimer des doublons dans le tableau de données d'origine, comme ceci:

var data = [{'name': 'Amir', 'surname': 'Rahnama'}, {'name': 'Amir', 'surname': 'Stevens'}];
var non_duplidated_data = _.uniq(data, 'name'); 

METTRE À JOUR: Lodash a maintenant introduit un .uniqBy ainsi que.


63
2017-11-26 15:37



J'ai exactement la même exigence pour supprimer les objets en double dans un tableau, en fonction des doublons sur un seul champ. J'ai trouvé le code ici: Javascript: supprimer des doublons d'un tableau d'objets

Donc, dans mon exemple, je supprime tout objet du tableau qui a une valeur de chaîne licenseNum en double.

var arrayWithDuplicates = [
    {"type":"LICENSE", "licenseNum": "12345", state:"NV"},
    {"type":"LICENSE", "licenseNum": "A7846", state:"CA"},
    {"type":"LICENSE", "licenseNum": "12345", state:"OR"},
    {"type":"LICENSE", "licenseNum": "10849", state:"CA"},
    {"type":"LICENSE", "licenseNum": "B7037", state:"WA"},
    {"type":"LICENSE", "licenseNum": "12345", state:"NM"}
];

function removeDuplicates(originalArray, prop) {
     var newArray = [];
     var lookupObject  = {};

     for(var i in originalArray) {
        lookupObject[originalArray[i][prop]] = originalArray[i];
     }

     for(i in lookupObject) {
         newArray.push(lookupObject[i]);
     }
      return newArray;
 }

var uniqueArray = removeDuplicates(arrayWithDuplicates, "licenseNum");
console.log("uniqueArray is: " + JSON.stringify(uniqueArray));

Les resultats:

uniqueArray est:

[{"type":"LICENSE","licenseNum":"10849","state":"CA"},
{"type":"LICENSE","licenseNum":"12345","state":"NM"},
{"type":"LICENSE","licenseNum":"A7846","state":"CA"},
{"type":"LICENSE","licenseNum":"B7037","state":"WA"}]

41
2017-07-26 16:32



Si vous pouvez attendre pour éliminer les doublons après toutes les additions, l'approche typique consiste à trier d'abord le tableau, puis éliminer les doublons. Le tri évite l'approche N * N consistant à balayer le tableau pour chaque élément lorsque vous les parcourez.

La fonction "éliminer les doublons" est généralement appelée unique ou uniq. Certaines implémentations existantes peuvent combiner les deux étapes, par exemple, prototype uniq

Ce post a peu d'idées à essayer (et d'autres à éviter :-)) si votre bibliothèque n'en a pas déjà! Personnellement, je trouve celui-ci le plus simple:

    function unique(a){
        a.sort();
        for(var i = 1; i < a.length; ){
            if(a[i-1] == a[i]){
                a.splice(i, 1);
            } else {
                i++;
            }
        }
        return a;
    }  

    // Provide your own comparison
    function unique(a, compareFunc){
        a.sort( compareFunc );
        for(var i = 1; i < a.length; ){
            if( compareFunc(a[i-1], a[i]) === 0){
                a.splice(i, 1);
            } else {
                i++;
            }
        }
        return a;
    }

21
2018-02-08 02:07



Voici une autre option pour le faire en utilisant les méthodes d'itération Array si vous n'avez besoin de la comparaison que par un seul champ d'un objet:

    function uniq(a, param){
        return a.filter(function(item, pos, array){
            return array.map(function(mapItem){ return mapItem[param]; }).indexOf(item[param]) === pos;
        })
    }

    uniq(things.thing, 'place');

17
2018-03-26 14:06



Un liner avec Set

var things = new Object();

things.thing = new Array();

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

// assign things.thing to myData for brevity
var myData = things.thing;

things.thing = Array.from(new Set(myData.map(JSON.stringify))).map(JSON.parse);

console.log(things.thing)

Explication:

  1. new Set(myData.map(JSON.stringify)) crée un Ensemble objet à l'aide des éléments myData stringifiés.
  2. Set object s'assurera que chaque élément est unique.
  3. Ensuite, je crée un tableau basé sur les éléments de l'ensemble créé en utilisant Array.from.
  4. Enfin, j'utilise JSON.parse pour convertir l'élément stringifié en un objet.

15
2018-06-17 06:30