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.
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; });
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.
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"
}
]
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;
});
}
Sie können lodash verwenden, um doppelte Objekte zu entfernen:
import * as _ from 'lodash';
_.uniqBy(data, 'id');
Hier ist 'id
' Ihre eindeutige Kennung
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);
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);
}
});
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
Versuchen Sie die folgende Funktion:
function trim(items){
const ids = [];
return items.filter(item => ids.includes(item.id) ? false : ids.Push(item.id));
}
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!
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');
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.