webentwicklung-frage-antwort-db.com.de

JavaScript: Entfernen Sie Duplikate von Objekten, die denselben Eigenschaftswert haben

Ich habe ein Array von Objekten, die ich basierend auf einem bestimmten key:value-Paar beschneiden möchte. Ich möchte ein Array erstellen, das nur ein Objekt für dieses key:value-Paar enthält. Es ist nicht unbedingt wichtig, welches Objekt der Duplikate in das neue Array kopiert wird.

Zum Beispiel möchte ich basierend auf der price-Eigenschaft von arrayWithDuplicates trimmen und ein neues Array erstellen, das nur einen Wert von jedem Wert enthält:

var arrayWithDuplicates = [
  {"color":"red", 
    "size": "small",
    "custom": {
      "inStock": true,
      "price": 10
    }
  },
  {"color":"green", 
    "size": "small",
    "custom": {
      "inStock": true,
      "price": 30
    }
  },
  {"color":"blue", 
    "size": "medium",
    "custom": {
      "inStock": true,
      "price": 30
    }
  },
  {"color":"red", 
    "size": "large",
    "custom": {
      "inStock": true,
      "price": 20
    }
  }
];

Würde werden:

var trimmedArray = [
  {"color":"red", 
    "size": "small",
    "custom": {
      "inStock": true,
      "price": 10
    }
  },
  {"color":"green", 
    "size": "small",
    "custom": {
      "inStock": true,
      "price": 30
    }
  },
  {"color":"red", 
    "size": "large",
    "custom": {
      "inStock": true,
      "price": 20
    }
  }
];

Gibt es eine JavaScript- oder Angular-Funktion, die durchlaufen würde und dies tun würde?

BEARBEITEN: Die zu filternde Eigenschaft ist in einer anderen Eigenschaft verschachtelt.

24
Lauren F

Sie können Unterstrich dafür verwenden:

//by size:
var uSize = _.uniq(arrayWithDuplicates, function(p){ return p.size; });

//by custom.price;
var uPrice = _.uniq(arrayWithDuplicates, function(p){ return p.custom.price; });
4
user3335966
function removeDuplicatesBy(keyFn, array) {
  var mySet = new Set();
  return array.filter(function(x) {
    var key = keyFn(x), isNew = !mySet.has(key);
    if (isNew) mySet.add(key);
    return isNew;
  });
}

verwendung (EcmaScript6-Pfeilfunktionen lassen es besser aussehen):

removeDuplicatesBy(x => x.custom.price, yourArrayWithDuplicates);

BEARBEITEN: Das bearbeitete Snippet dient nicht dazu, den Eigenschaftennamen zu verwenden, sondern eine Schlüsselauswahlfunktion, um verschachtelte Eigenschaften zu erreichen.

23
Tamas Hegedus

Ich glaube nicht, dass es in Angular eine integrierte Funktion gibt, aber es ist nicht schwer, eine zu erstellen:

function removeDuplicates(originalArray, objKey) {
  var trimmedArray = [];
  var values = [];
  var value;

  for(var i = 0; i < originalArray.length; i++) {
    value = originalArray[i][objKey];

    if(values.indexOf(value) === -1) {
      trimmedArray.Push(originalArray[i]);
      values.Push(value);
    }
  }

  return trimmedArray;

}

Verwendungszweck:

removeDuplicates(arrayWithDuplicates, 'size');

Kehrt zurück:

[
    {
        "color": "red",
        "size": "small"
    },
    {
        "color": "blue",
        "size": "medium"
    },
    {
        "color": "red",
        "size": "large"
    }
]

Und

removeDuplicates(arrayWithDuplicates, 'color');

Kehrt zurück:

[
    {
        "color": "red",
        "size": "small"
    },
    {
        "color": "green",
        "size": "small"
    },
    {
        "color": "blue",
        "size": "medium"
    }
]
12
yvesmancera

Verwenden Sie Array.filter(), verfolgen Sie Werte, indem Sie eine Object als Hash verwenden, und filtern Sie alle Elemente heraus, deren Wert bereits im Hash enthalten ist.

function trim(arr, key) {
    var values = {};
    return arr.filter(function(item){
        var val = item[key];
        var exists = values[val];
        values[val] = true;
        return !exists;
    });
}
7
gilly3

Sie können lodash verwenden, um doppelte Objekte zu entfernen:

 import * as _ from 'lodash';
  _.uniqBy(data, 'id');

Hier ist 'id' Ihre eindeutige Kennung 

2
Mukesh Ranjan
for (let i = 0; i < arrayWithDuplicates.length; i++) {
     for (let j = i + 1; j < arrayWithDuplicates.length; j++) {
       if (arrayWithDuplicates[i].name === students[j].name) {
          arrayWithDuplicates.splice(i, 1);
       }
     }
    }

this will work perfectly...and this will delete first repeated array.
To delete last repeated array we only have to change
 arrayWithDuplicates.splice(i, 1) ; into
 arrayWithDuplicates.splice(j, 1);
1
sudha priya

Einfache Lösung, obwohl nicht die leistungsfähigste:

var unique = [];
duplicates.forEach(function(d) {
    var found = false;
    unique.forEach(function(u) {
        if(u.key == d.key) {
            found = true;
        }
    });
    if(!found) {
        unique.Push(d);
    }
});
1
Souvik Basu

mit lodash können Sie es einfach herausfiltern

der erste Parameter ist Ihr Array und der zweite ist Ihr Feld mit Duplikaten

_.uniqBy(arrayWithDuplicates, 'color')

es wird ein Array mit eindeutigem Wert zurückgegeben 

1
yureka

Versuchen Sie die folgende Funktion:

function trim(items){
    const ids = [];
    return items.filter(item => ids.includes(item.id) ? false : ids.Push(item.id));
}
0
sliter

Ganz oben in meinem Kopf gibt es keine einzige Funktion, die dies für Sie tun wird, wenn Sie sich mit einem Array von Objekten befassen, und es gibt auch keine Regel, bei der Duplikate als Duplikate entfernt würden.

In Ihrem Beispiel entfernen Sie die Datei mit size: small. Wenn Sie dies jedoch mithilfe einer Schleife implementieren, schließen Sie wahrscheinlich die erste ein und schließen die letzte aus, während Sie Ihr Array durchlaufen.

Es lohnt sich vielleicht, einen Blick in eine Bibliothek wie lodash zu werfen und eine Funktion zu erstellen, die eine Kombination ihrer API-Methoden verwendet, um das gewünschte Verhalten zu erhalten.

Hier ist eine mögliche Lösung, die Sie verwenden können, indem Sie grundlegende Arrays und einen Filterausdruck verwenden, um zu prüfen, ob ein neues Element als Duplikat betrachtet wird, bevor es an ein Ergebnis der Rückgabe angehängt wird.

var arrayWithDuplicates = [
    {"color":"red", "size": "small"},
    {"color":"green", "size": "small"},
    {"color":"blue", "size": "medium"},
    {"color":"red", "size": "large"}
];

var reduce = function(arr, prop) {
  var result = [],
      filterVal,
      filters,
      filterByVal = function(n) {
          if (n[prop] === filterVal) return true;
      };
  for (var i = 0; i < arr.length; i++) {
      filterVal = arr[i][prop];
      filters   = result.filter(filterByVal);
      if (filters.length === 0) result.Push(arr[i]);
  }
  return result;
};

console.info(reduce(arrayWithDuplicates, 'color'));

Weitere Informationen zur Array-Filterung finden Sie in hier Wenn Sie festlegen möchten, welches Element entfernt werden soll, können Sie zusätzliche Parameter und Logik definieren, die zusätzliche Eigenschaftsprüfungen durchführen, bevor Sie einen Rückgabewert hinzufügen.

Hoffentlich hilft das!

0
jh3y

Hier ist der TypeScript-Weg

    public removeDuplicates(originalArray:any[], prop) {
    let newArray = [];
    let lookupObject = {};

    originalArray.forEach((item, index) => {
        lookupObject[originalArray[index][prop]] = originalArray[index];
    });

    Object.keys(lookupObject).forEach(element => {
        newArray.Push(lookupObject[element]);
    });
    return newArray;
}

Und

let output = this.removeDuplicates(yourArray,'color');
0
Praveen M P

Dies ist nur ein weiteres "Feature", das auf der Lösung von yvesmancera basiert (nachdem ich angefangen habe, an meiner eigenen Lösung zu basteln). Außerdem ist zu beachten, dass wir derzeit nur IE 11 verwenden dürfen, daher ist begrenztes ES5 zulässig.

var newArray = RemoveDuplicates(myArray,'Role', 2);

function RemoveDuplicates(array, objKey, rtnType) {
var list = [], values = [], value;
for (var i = 0; i < array.length; i++) {
    value = array[i][objKey];
    if(values.indexOf(value) === -1){
        list.Push(array[i]);
        values.Push(value);
        }
    }
    if(rtnType == 1)
        return list;
    return values;
};

Hoffen Sie, dass dies für die meisten, wenn nicht für alle Arrays funktioniert, wenn Sie Objekte basierend auf einem einzelnen Objekteigenschaftswert herausfiltern.

0
Keltanis