Ich habe eine Reihe von Objekten, die so aussehen:
var array = [
{id:123, value:"value1", name:"Name1"},
{id:124, value:"value2", name:"Name1"},
{id:125, value:"value3", name:"Name2"},
{id:126, value:"value4", name:"Name2"}
...
];
Wie Sie sehen können, werden einige Namen wiederholt. Ich möchte ein neues Array nur mit Namen erhalten, aber wenn sich ein Name wiederholt, möchte ich ihn nicht erneut hinzufügen. Ich möchte dieses Array:
var newArray = ["Name1", "Name2"];
Ich versuche das mit map
:
var newArray = array.map((a) => {
return a.name;
});
Das Problem ist jedoch, dass dies zurückkehrt:
newArray = ["Name1", "Name1", "Name2", "Name2"];
Wie kann ich eine Bedingung festlegen map
, damit kein bereits vorhandenes Element zurückgegeben wird? Ich möchte dies mit map
oder einer anderen ECMAScript 5- oder ECMAScript 6-Funktion tun .
javascript
arrays
snoopy25
quelle
quelle
Set
? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Antworten:
Mit ES6 können Sie
Set
eindeutige Werte verwenden, nachdem Sie nur die Namen der Objekte zugeordnet haben.Dieser Vorschlag verwendet eine Spread-Syntax
...
zum Sammeln der Elemente in einem neuen Array.quelle
...
das?...
zum Erstellen eines Arrays mit einem iterierbaren Objekt.Array.from
vermittelt die Absicht der Konvertierung viel besser (und ist auch leichter zu verstehen / nach Neulingen zu suchen). Die Spread-Syntax sollte nur verwendet werden, wenn das verteilte Element eines von vielen ist. Vielleicht ist es ein bisschen zu hart, es als "schlechte Praxis" zu bezeichnen. Tut mir leid, ich hoffe nur, dass es nicht zu einer gängigen Redewendung wird.Wenn Sie nach einer JavaScript-Lösung suchen, die nicht ES 6 (no Set) ist, können Sie die
reduce
Methode des Arrays verwenden :quelle
var names = array.reduce(function(a, b) { a.indexOf(b.name) === -1 && a.push(b.name) return a; }, []);
Persönlich verstehe ich nicht, warum alle Lust auf ES 6 haben. Wenn es mein Code wäre, würde ich es vorziehen, so viele Browser wie möglich zu unterstützen.
quelle
indexOf
ständig zu arbeiten? ZB tunadded[name] = true
undif(added[name])
stattif(a.indexOf(name))
.goto fail
, verlieren Ihre Indexvariable in den umschließenden Bereich usw. usw. ES6 wurde aus guten Gründen in den Standard kodifiziert und ist für die meisten Teil für ältere Browser trivial einfach zu füllen / zu transformieren.Sie könnten auch einfach kombinieren
map
mitfilter
quelle
Sie können Object.keys () verwenden , um das Array der eigenen aufzählbaren Eigenschaftsnamen eines bestimmten Objekts aus dem Objektergebnis der iterierenden
array
Variablen mit Array.prototype.reduce () abzurufen, wobei die Schlüssel die zerstörten Namen sindCode:
quelle
Viele gute Antworten hier. Ich möchte nur mit etwas Abwechslung dazu beitragen, Ihnen eine andere Perspektive zu geben.
Arrays sind in JavaScript vom Objekttyp, sodass sie gleichzeitig als Hash verwendet werden können. Durch die Verwendung dieser Funktionalität können wir die Arbeit in einem einzigen Reduktionsvorgang mit O (n) -Zeitkomplexität erheblich vereinfachen.
Wenn Sie nicht zufrieden sind, dass Ihr Array andere Eigenschaften als die Array-Schlüssel enthält, können Sie auch ein separates Hash-Objekt behalten.
quelle
p[c.name]
Zeug auf einem separaten Objekt zu macheno
und es anschließend zu verwerfen.Ich bin damit einverstanden, dass a der
name
richtigeSet
Weg ist , wenn Sie nur die Werte benötigen .Allerdings , wenn Sie wollen auf der eine Reihe von einzigartigen Objekten erhalten basierte
name
Eigenschaft, würde ich vorschlagen , eine verwendenMap
. Eine schnelle Möglichkeit zum Erstellen einer Karte besteht in einer Reihe von[key, value]
Arrays:Ein zusätzlicher Vorteil von
Map
ist, dass Sie beidefilter
Funktionen erhalten, die die Nicht-Unikate ausschneiden, ohne die Verbindung mit den Quellobjekten zu verlieren. Natürlich ist es nur erforderlich, wenn Sie mehrmals auf den eindeutigen Satz von Objekten verweisen müssen.quelle
Wenn Sie auf ES5 beschränkt sind, würde ich Lodashs verwenden
_.uniq
quelle
Mit ES6 sollte dies den Job machen.
quelle
map
soll mit reinen Funktionen verwendet werden, keine Nebenwirkungen haben. Dies wäre ein Job fürforEach
oderreduce
.Verwenden von UnderscoreJS,
`
quelle
Verwenden Sie in ES5 ein Objekt als Wörterbuch für die O ( n ) -Leistung.
Dies funktioniert nur, wenn alle Schlüssel Strings sind.
Sie können dasselbe in einem Ausdruck tun, wenn Sie möchten:
aber ich finde die imperative Form leichter zu lesen.
quelle
function (item) { return item.name; }
Object.keys()
, diese Antwort Verwendungenfilter()
zu halten diese Namen nur , die noch nicht in der Karte gespeichert sind, die sehr elegant ist.Versuche dies:
quelle
Verwenden Sie
array#forEach()
undarray#indexOf()
Methoden wie diese, wenn Sie noch maximale Kompatibilität wünschen , prägnante Syntax:Wenn die Kompatibilität jedoch kein Problem darstellt, verwenden Sie das Objekt von ECMAScript 6 und folgende Methoden:
Set
array#map
Array.from()
quelle
So habe ich es gemacht, indem ich ein separates leeres Array verwendet habe.
quelle
Für diejenigen, die einen 1 Liner suchen
oder ohne Verwendung von Methoden für den Prototyp des Arrays
könnte nützlich sein, um einige reine Funktionen zu schreiben, um damit umzugehen
quelle
quelle