2017-05-09 3 views
0

Ich kämpfe mit Entfernen von Dupes aus einer Reihe von Objekten. Ich habe ein Array, storedItems:gebe ein gefiltertes Array von Objekten zurück

var storedItems = [ 
    {text: "1", checked: false }, 
    {text: "2", checked: false }, 
    {text: "3", checked: false }, 
    {text: "string", checked: false } 
] 

usw. Die Textwerte sind entweder Zeichenfolgen oder numerische Zeichenfolgen. Ich bin ok mit den einzigartigen Textwerte zu identifizieren, entweder in der Hash oder in uniqueVals ...

filterDupes(storedItems); 

function filterDupes(input) { 
    var hash = {}; 
    var uniqueVals = []; 
    input.forEach(obj => { 
     hash[obj.text] = true; 
    }) 
    var uniqueVals = Object.keys(hash); // Array 
    return input.filter(function(obj, ix, arr) { 
     uniqueVals.indexOf(obj.text) !== -1; // NOPE 
    }) // .filter 
} // filterDupes 

... es ist wie entweder den Hash-Schlüssel oder uniqueVals an den Eingang Array Objekte zu vergleichen, das heißt, was genau brauche ich (ohne eine for-Schleife oder eine andere forEach?), um das gefilterte Array zurückzugeben, das hat mich dazu gebracht, meinen Kopf gegen eine Wand zu schlagen, um eine Version von return hash zu finden [obj.text] == ​​obj.text; oder return (hash.key === obj.text)

EDIT: Geige hier: https://jsfiddle.net/WTFoxtrot/by3nhy4n/2/

+0

Sie wollen wahrscheinlich Set Objekt https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Set statt laufen forEach Schleife dann Object.keys Methode verwenden. – Yanaro

+0

Was macht der Code, den du gezeigt hast, jetzt? Funktioniert es nicht? Wenn es nicht funktioniert, wie funktioniert es nicht? –

+0

@Yanaro re: Set-Objekt, ja, ich habe gerade davon erfahren, danke. –

Antwort

1

Mit einer Kombination aus Array.prototype.map() und Array.prototype.filter():

let items = [ 
 
    {text: "1", checked: false}, 
 
    {text: "2", checked: false}, 
 
    {text: "3", checked: false}, 
 
    {text: "string", checked: false}, 
 
    {text: "2", checked: false}, 
 
    {text: "string", checked: false}, 
 
    {text: "1", checked: false} 
 
]; 
 
let values = items.map(it => it.text).filter((v, i, a) => a.indexOf(v) === i); 
 

 
console.log(values); // ["1", "2", "3", "string"]

Der Filter Der Abschluss (v, i, a) => a.indexOf(v) === i filtert alle Werte aus, die an einer anderen Position als dem ersten Auftreten dieses Werts vorhanden sind.

Mit den gleichen Prinzipien, wenn Sie das Array von Objekten selbst statt der Rückkehr eine Liste von eindeutigen Werten filtern möchten, können Sie Array.prototype.filter() mit Array.prototype.find() verwenden:

let items = [ 
 
    {text: "1", checked: false}, 
 
    {text: "2", checked: false}, 
 
    {text: "3", checked: false}, 
 
    {text: "string", checked: false}, 
 
    {text: "2", checked: false}, 
 
    {text: "string", checked: false}, 
 
    {text: "1", checked: false} 
 
]; 
 
let filtered = items.filter((x, i, a) => a.find(y => x.text === y.text) === x); 
 

 
console.log(filtered); // [{"text": "1", "checked": false}, {"text": "2", "checked": false}, {"text": "3", "checked": false}, {"text": "string", "checked": false}]

+0

Danke! Ihre v2 ist was ich brauchte: Ich wollte das gefilterte Array von Objekten, nicht nur die uniqueVals, die ich hatte, mit dem Hash zurückgeben. Ich bin neugierig auf ein paar Dinge; dachte ich woanders gelesen, dass die Verwendung eines Hash oder Set() ist effizienter als indexof, obwohl ich mir nicht vorstellen kann, wie seit Ihrer v1-Werte-Anweisung ist so schön. Englisch: www.mjfriendship.de/en/index.php?op...39&Itemid=32 Während ich weiter über .find() lese, würde ich es sehr schätzen, wenn Sie eine Minute, eine Erklärung der.Aussage finden - das ist ein bisschen verrückt. Prost, W –

2

V2: Wenn Sie das Set-Objekt verwenden, verwenden Sie Array-Index auf die gleiche Weise:

Wenn Sie nicht möchten, dass Ihre Funktion ändern zu viel:

... 
return input.filter((obj, ix, arr) => { 
    var index = uniqueVals.indexOf(obj.text); 
    if(index !== -1) { 
    // Remove the element from unique array 
     uniqueVals.splice(index,1); 
     return true; 
    } 
    return false; 
}) 

V1: Falsche. Zuvor ist Ihre Funktion nicht korrekt. Es tut tatsächlich nichts. Sie schieben den Text nur auf ein Array und überprüfen dann erneut, ob der Text in diesem Array vorhanden ist.

var storedItems = [ 
    {text: "1", checked: false }, 
    {text: "2", checked: false }, 
    {text: "3", checked: false }, 
    {text: "string", checked: false } 
]; 

function filterDupes(input) { 
    //Your previous code inside function 
    ... 
    return input.filter(function(obj, ix, arr) { 
    return uniqueVals.indexOf(obj.text) !== -1; 
    }) 
} 
+0

Danke. Die Semikola im Objekt waren Tippfehler, ich habe meinen Beitrag bearbeitet und sie entfernt. Ich denke, meine Geige (URL in meinem Post) ist, was Sie vorschlagen, aber immer noch habe ich nichts zurückgegeben (eigentlich in jdfiddle bekomme ich nichts, und in einem Repl ich ein leeres Objekt zurück). Was vermisse ich? –

+0

Vielen Dank für die Ausarbeitung. Im Interesse des Verständnisses habe ich beides versucht. Ich * schätze * sehr, dass Sie eine Lösung anbieten, die auf dem aufbaut, was ich hatte; persönlich finde ich das sehr hilfreich, vielleicht aufgrund von Sturheit aber trotzdem. Das heißt, sobald ich Ihre V1 groked, bevorzuge ich es, weil es klar und offensichtlich prägnanter ist. Ich bevorzuge es tatsächlich der Antwort, die ich akzeptierte, da es lernfreundlicher ist (aber vielleicht ist es schlecht, die akzeptierte Antwort zu ändern). Ich wünsche mehr Antworten auf SO, wo die OP herkommt. Prost! –

Verwandte Themen