953 Stimmen

Wie entfernt man alle Duplikate aus einem Array von Objekten?

Ich habe ein Objekt, das ein Array von Objekten enthält.

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"});

Ich frage mich, was ist die beste Methode zum Entfernen von doppelten Objekten aus einem Array. Also zum Beispiel, obj.arr werden würde...

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

40voto

chickens Punkte 14182

One-Liner mit Karte ( Hohe Leistung, erhält nicht die Ordnung )

Einzigartig finden id im Array arr .

const arrUniq = [...new Map(arr.map(v => [v.id, v])).values()]

Wenn die Reihenfolge wichtig ist, sehen Sie sich die Lösung mit Filter an: Lösung mit Filter


Eindeutig durch mehrere Eigenschaften ( place y name ) im Array arr

const arrUniq = [...new Map(arr.map(v => [JSON.stringify([v.place,v.name]), v])).values()]

Eindeutig für alle Eigenschaften im Array arr

const arrUniq = [...new Map(arr.map(v => [JSON.stringify(v), v])).values()]

Das erste Vorkommen im Array behalten arr

const arrUniq = [...new Map(arr.slice().reverse().map(v => [v.id, v])).values()].reverse()

31voto

Alex Kobylinski Punkte 329

Hier ist eine weitere Möglichkeit, es mit Array iterating Methoden zu tun, wenn Sie Vergleich nur durch ein Feld eines Objekts benötigen:

    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');

26voto

Tim Down Punkte 304837

Dies ist ein allgemeiner Weg, dies zu tun: Sie übergeben eine Funktion, die prüft, ob zwei Elemente eines Arrays als gleichwertig angesehen werden. In diesem Fall vergleicht sie die Werte der name y place Eigenschaften der beiden zu vergleichenden Objekte.

ES5-Antwort

function removeDuplicates(arr, equals) {
    var originalArr = arr.slice(0);
    var i, len, val;
    arr.length = 0;

    for (i = 0, len = originalArr.length; i < len; ++i) {
        val = originalArr[i];
        if (!arr.some(function(item) { return equals(item, val); })) {
            arr.push(val);
        }
    }
}

function thingsEqual(thing1, thing2) {
    return thing1.place === thing2.place
        && thing1.name === thing2.name;
}

var things = [
  {place:"here",name:"stuff"},
  {place:"there",name:"morestuff"},
  {place:"there",name:"morestuff"}
];

removeDuplicates(things, thingsEqual);
console.log(things);

Original ES3-Antwort

function arrayContains(arr, val, equals) {
    var i = arr.length;
    while (i--) {
        if ( equals(arr[i], val) ) {
            return true;
        }
    }
    return false;
}

function removeDuplicates(arr, equals) {
    var originalArr = arr.slice(0);
    var i, len, j, val;
    arr.length = 0;

    for (i = 0, len = originalArr.length; i < len; ++i) {
        val = originalArr[i];
        if (!arrayContains(arr, val, equals)) {
            arr.push(val);
        }
    }
}

function thingsEqual(thing1, thing2) {
    return thing1.place === thing2.place
        && thing1.name === thing2.name;
}

removeDuplicates(things.thing, thingsEqual);

26voto

maccullt Punkte 2719

Wenn Sie mit der Eliminierung der Duplikate warten können, bis alle Hinzufügungen erfolgt sind, besteht der typische Ansatz darin, das Array zuerst zu sortieren und dann die Duplikate zu eliminieren. Die Sortierung vermeidet den N * N-Ansatz des Scannens des Arrays für jedes Element, während Sie durch sie gehen.

Die Funktion "Duplikate eliminieren" wird normalerweise aufgerufen einzigartig ou uniq . Einige bestehende Implementierungen können die beiden Schritte kombinieren, z. B., Prototyp ist einmalig

Diese Stelle hat einige Ideen zum Ausprobieren (und einige zum Vermeiden :-) ) falls Ihre Bibliothek nicht bereits eine hat ! Ich persönlich finde diese Variante am einfachsten:

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

23voto

doğukan Punkte 16869

Ich denke, der beste Ansatz ist die Verwendung von reduzieren. y Kartenobjekt . Dies ist eine einzeilige Lösung.

const data = [
  {id: 1, name: 'David'},
  {id: 2, name: 'Mark'},
  {id: 2, name: 'Lora'},
  {id: 4, name: 'Tyler'},
  {id: 4, name: 'Donald'},
  {id: 5, name: 'Adrian'},
  {id: 6, name: 'Michael'}
]

const uniqueData = [...data.reduce((map, obj) => map.set(obj.id, obj), new Map()).values()];

console.log(uniqueData)

/*
  in `map.set(obj.id, obj)`

  'obj.id' is key. (don't worry. we'll get only values using the .values() method)
  'obj' is whole object.
*/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X