Ich habe ein JavaScript-Objektarray mit der folgenden Struktur:
objArray = [ { foo: 1, bar: 2}, { foo: 3, bar: 4}, { foo: 5, bar: 6} ];
Ich möchte aus jedem Objekt ein Feld extrahieren und ein Array mit den Werten abrufen, z. B. Feld foo
würde ergeben [ 1, 3, 5 ]
.
Ich kann dies mit diesem trivialen Ansatz tun:
function getFields(input, field) {
var output = [];
for (var i=0; i < input.length ; ++i)
output.push(input[i][field]);
return output;
}
var result = getFields(objArray, "foo"); // returns [ 1, 3, 5 ]
Gibt es eine elegantere oder idiomatischere Möglichkeit, dies zu tun, sodass eine benutzerdefinierte Dienstprogrammfunktion nicht erforderlich wäre?
Hinweis zum vorgeschlagenen Duplikat. Hier erfahren Sie, wie Sie ein einzelnes Objekt in ein Array konvertieren .
var foos = objArray.pluck("foo");
.Array.prototype.map
Funktion vergleichen, wo es existiertAntworten:
Hier ist ein kürzerer Weg, um dies zu erreichen:
ODER
Sie können auch überprüfen
Array.prototype.map()
.quelle
Ja, aber es basiert auf einer ES5-Funktion von JavaScript. Dies bedeutet, dass es in IE8 oder älter nicht funktioniert.
Auf ES6 kompatibel JS Dolmetscher können Sie einen verwenden Pfeil Funktion der Kürze:
Array.prototype.map-Dokumentation
quelle
foo
?var result = objArray.map((a) => (a.foo));
var result = objArray.map(a => a.foo);
Schauen Sie sich die
_.pluck()
Funktion von Lodash oder Underscore an_.pluck()
. Beide machen in einem einzigen Funktionsaufruf genau das, was Sie wollen!Update:
_.pluck()
wurde ab Lodash v4.0.0 entfernt , zugunsten von_.map()
in Kombination mit etwas ähnlichem wie Niets Antwort ._.pluck()
ist weiterhin in Unterstrich verfügbar .Update 2: Wie Mark betont in den Kommentaren hervorhebt, wurde irgendwo zwischen Lodash v4 und 4.3 eine neue Funktion hinzugefügt, die diese Funktionalität wieder bereitstellt.
_.property()
ist eine Kurzfunktion, die eine Funktion zum Abrufen des Werts einer Eigenschaft in einem Objekt zurückgibt.Zusätzlich,
_.map()
jetzt eine Zeichenfolge als zweiter Parameter übergeben werden, an den übergeben wird_.property()
. Infolgedessen entsprechen die folgenden zwei Zeilen dem obigen Codebeispiel aus Pre-Lodash 4._.property()
, und daher_.map()
auch eine durch Punkte getrennte Zeichenfolge oder ein Array bereitstellen, um auf Untereigenschaften zuzugreifen:Beide
_.map()
Aufrufe im obigen Beispiel werden zurückgegeben[5, 2, 9]
.Wenn Sie sich ein wenig mehr mit funktionaler Programmierung beschäftigen, werfen Sie einen Blick auf Ramdas
R.pluck()
Funktion, die ungefähr so aussehen würde:quelle
_.property('foo')
( lodash.com/docs#property ) wurde als Abkürzung für hinzugefügtfunction(o) { return o.foo; }
. Dies verkürzt den Lodash-Anwendungsfall aufvar result = _.pluck(objArray, _.property('foo'));
Zur weiteren Bequemlichkeit ermöglicht die_.map()
Methode von Lodash 4.3.0 auch die Verwendung einer Kurzschrift_.property()
unter der Haube, was dazu führt, dassvar result = _.map(objArray, 'foo');
Ich habe festgestellt, dass eine einfache indizierte
for
Schleife , so unelegant sie auch sein mag, leistungsfähiger ist als ihre Alternativen.Extrahieren einer einzelnen Eigenschaft aus einem 100000-Element-Array (über jsPerf)
Traditionell für Schleife 368 Ops / Sek
ES6 für die Schleife 303 Ops / Sek
Array.prototype.map 19 Ops / Sek
TL; DR - .map () ist langsam, aber Sie können es gerne verwenden, wenn Sie der Meinung sind, dass Lesbarkeit mehr wert ist als Leistung.
Edit # 2: 6/2019 - jsPerf-Link unterbrochen, entfernt.
quelle
Es ist besser, eine Art von Bibliotheken wie lodash oder Unterstrich für die browserübergreifende Sicherheit zu verwenden.
In Lodash können Sie Werte einer Eigenschaft im Array mithilfe der folgenden Methode abrufen
und in Unterstrich
Beide werden zurückkehren
quelle
Verwenden von
Array.prototype.map
:Unter dem obigen Link finden Sie eine Unterlegscheibe für Browser vor ES5.
quelle
In ES6 können Sie Folgendes tun:
quelle
Dies
map
ist zwar eine geeignete Lösung, um 'Spalten' aus einer Liste von Objekten auszuwählen, hat jedoch einen Nachteil. Wenn nicht explizit überprüft wird, ob die Spalten vorhanden sind oder nicht, wird ein Fehler ausgegeben und (bestenfalls) angezeigtundefined
. Ich würde mich für einereduce
Lösung entscheiden, die die Eigenschaft einfach ignorieren oder Sie sogar mit einem Standardwert einrichten kann.jsbin Beispiel
Dies würde auch dann funktionieren, wenn eines der Elemente in der bereitgestellten Liste kein Objekt ist oder das Feld nicht enthält.
Es kann sogar flexibler gestaltet werden, indem ein Standardwert ausgehandelt wird, falls ein Element kein Objekt ist oder das Feld nicht enthält.
jsbin Beispiel
Dies wäre bei map dasselbe, da die Länge des zurückgegebenen Arrays der Länge des bereitgestellten Arrays entsprechen würde. (In diesem Fall
map
ist a etwas billiger als areduce
):jsbin Beispiel
Und dann gibt es die flexibelste Lösung, mit der Sie zwischen beiden Verhaltensweisen wechseln können, indem Sie einfach einen alternativen Wert angeben.
jsbin Beispiel
Da die obigen Beispiele (hoffentlich) etwas Licht in die Funktionsweise bringen, können Sie die Funktion durch Verwendung der
Array.concat
Funktion etwas verkürzen .jsbin Beispiel
quelle
Wenn Sie Objektwerte extrapolieren möchten, die sich innerhalb eines Arrays befinden (wie in der Frage beschrieben), können Sie im Allgemeinen die Destrukturierung reduzieren, abbilden und Array verwenden.
ES6
Das Äquivalent für die for- Schleife wäre:
Produzierte Ausgabe: ["Wort", "wieder", "einige", "1", "2", "3"]
quelle
Es hängt von Ihrer Definition von "besser" ab.
Die anderen Antworten weisen auf die Verwendung von Karten hin, die natürlich (insbesondere für Männer, die an funktionalen Stil gewöhnt sind) und prägnant sind. Ich empfehle dringend, es zu verwenden (wenn Sie sich nicht mit den wenigen IE8-IT-Leuten beschäftigen). Wenn also "besser" "prägnanter", "wartbar", "verständlich" bedeutet, dann ist es viel besser.
Andererseits kommt diese Schönheit nicht ohne zusätzliche Kosten. Ich bin kein großer Fan von Microbench, aber ich habe hier einen kleinen Test durchgeführt . Das Ergebnis ist vorhersehbar, der alte hässliche Weg scheint schneller zu sein als die Kartenfunktion. Also, wenn "besser" "schneller" bedeutet, dann nein, bleiben Sie bei der alten Schulmode.
Auch dies ist nur eine Mikrobank und spricht sich in keiner Weise gegen die Verwendung von aus
map
, es sind nur meine zwei Cent :).quelle
map
ist der offensichtliche Weg, irgendwie habe ich ihn mit Google einfach nicht gefunden (ich habe nur die Karte von jquery gefunden, die nicht relevant ist).Wenn Sie auch Array-ähnliche Objekte unterstützen möchten, verwenden Sie Array.from (ES2015):
Der Vorteil gegenüber der Array.prototype.map () -Methode besteht darin, dass die Eingabe auch ein Set sein kann :
quelle
Wenn Sie mehrere Werte in ES6 + möchten, funktioniert Folgendes
Dies funktioniert wie
{foo, baz}
auf der linken Seite wird mit Objekt destructoring und auf der rechten Seite des Pfeils entspricht{foo: foo, baz: baz}
zurückzuführen ES6 des erweiterten Objektliterale .quelle
Die Funktionszuordnung ist eine gute Wahl, wenn es um Objektarrays geht. Obwohl bereits einige gute Antworten veröffentlicht wurden, kann das Beispiel der Verwendung einer Karte mit Kombination mit Filter hilfreich sein.
Wenn Sie die Eigenschaften ausschließen möchten, deren Werte nicht definiert sind, oder nur eine bestimmte Eigenschaft ausschließen möchten, können Sie Folgendes tun:
https://jsfiddle.net/ohea7mgk/
quelle
Die oben angegebene Antwort eignet sich zum Extrahieren einer einzelnen Eigenschaft. Was ist, wenn Sie mehr als eine Eigenschaft aus einem Array von Objekten extrahieren möchten? Hier ist die Lösung !! In diesem Fall können wir einfach _.pick (Objekt, [Pfade]) verwenden.
Nehmen wir an, objArray hat Objekte mit drei Eigenschaften wie unten
Jetzt wollen wir foo- und bar-Eigenschaften aus jedem Objekt extrahieren und in einem separaten Array speichern. Zuerst werden wir Array-Elemente mit map iterieren und dann die Lodash Library Standard _.pick () -Methode darauf anwenden.
Jetzt können wir die Eigenschaften 'foo' und 'bar' extrahieren.
var newArray = objArray.map((element)=>{ return _.pick(element, ['foo','bar'])}) console.log(newArray);
und das Ergebnis wäre [{foo: 1, bar: 2}, {foo: 3, bar: 4}, {foo: 5, bar: 6}]
genießen!!!
quelle
_.pick
das? Es ist keine Standardfunktion.Wenn Sie verschachtelte Arrays haben, können Sie dies folgendermaßen ausführen:
quelle