Wenn ich ein Array von Zeichenfolgen habe, kann ich die verwenden .join()
Methode verwenden, um eine einzelne Zeichenfolge abzurufen, wobei jedes Element wie folgt durch Kommas getrennt ist:
["Joe", "Kevin", "Peter"].join(", ") // => "Joe, Kevin, Peter"
Ich habe eine Reihe von Objekten und möchte eine ähnliche Operation für einen darin enthaltenen Wert ausführen. also von
[
{name: "Joe", age: 22},
{name: "Kevin", age: 24},
{name: "Peter", age: 21}
]
Führen Sie die join
Methode nur für das name
Attribut aus, um die gleiche Ausgabe wie zuvor zu erzielen.
Derzeit habe ich folgende Funktion:
function joinObj(a, attr){
var out = [];
for (var i = 0; i < a.length; i++){
out.push(a[i][attr]);
}
return out.join(", ");
}
An diesem Code ist nichts auszusetzen, er funktioniert, aber plötzlich bin ich von einer einfachen, prägnanten Codezeile zu einer sehr wichtigen Funktion übergegangen. Gibt es eine prägnantere, idealerweise funktionalere Schreibweise?
javascript
arrays
object
Jackweirdy
quelle
quelle
" ,".join([i.name for i in a])
users.map(x => x.name).join(', ');
.Antworten:
Wenn Sie Objekte etwas zuordnen möchten (in diesem Fall eine Eigenschaft). Ich denke, es
Array.prototype.map
ist das, wonach Sie suchen, wenn Sie funktional codieren möchten.In modernem JavaScript:
(Geige)
Wenn Sie ältere Browser unterstützen möchten, die nicht ES5-kompatibel sind , können Sie diese anpassen (auf der MDN-Seite oben befindet sich eine Polyfüllung). Eine andere Alternative wäre die Verwendung der
pluck
Methode von underscorejs :quelle
[x.name for x of users]
(spezifizieren Sie wiki.ecmascript.org/doku.php?id=harmony:array_comprehensions ). Erwähnenswert ist, dass genau wie die Verwendung von Map / Reduce / Filter nicht sehr "pythonisch" ist, wie es in JavaScript wahrscheinlich der andere Weg ist. CoffeeScript ist cool mit ihnen, obwohl coffeescript.org .users.map((obj) -> obj.name).join(', ')
Nun, Sie können die
toString
Methode Ihrer Objekte jederzeit überschreiben :quelle
toString
mithilfe einer for-Schleife der Methode aller Elemente zuweisen . Sie können diesen Ansatz auch verwenden, wenn Sie sich mit Konstruktorfunktionen befassen, indem SietoString
derprototype
Eigenschaft für den Konstruktor eine Methode hinzufügen . Dieses Beispiel sollte jedoch nur das Grundkonzept zeigen.Ich bin auch auf die
reduce
Methode gestoßen, so sieht es aus:Das
(a.name || a)
ist so, dass das erste Element korrekt behandelt wird, aber der Rest (woa
ein String ist und somita.name
undefiniert) wird nicht als Objekt behandelt.Edit: Ich habe es jetzt weiter überarbeitet:
Was ich für sauberer halte, da
a
es immer eine Zeichenfolge ist,b
ist immer ein Objekt (aufgrund der Verwendung vonWas optionalen Parameters initialValue inreduce
).Bearbeiten 6 Monate später: Oh, was habe ich gedacht. "Reiniger". Ich habe den Code Gods verärgert.
quelle
reduce
wird nicht so häufig unterstützt wiemap
(was seltsam ist, wenn manIch weiß nicht, ob es einen einfacheren Weg gibt, ohne eine externe Bibliothek zu verwenden, aber ich persönlich liebe underscore.js, das unzählige Dienstprogramme für den Umgang mit Arrays, Sammlungen usw. enthält.
Mit Unterstrich können Sie dies einfach mit einer Codezeile tun:
_.pluck(arr, 'name').join(', ')
quelle
arr
ist Ihr Array natürlich)Auf Knoten oder ES6 +:
quelle
Angenommen, das Objektarray wird von der Variablen referenziert
users
Wenn ES6 verwendet werden kann, ist die einfachste Lösung:
Wenn nicht, und lodash kann so verwendet werden:
quelle
Wenn Objekt- und dynamische Schlüssel:
"applications\":{\"1\":\"Element1\",\"2\":\"Element2\"}
quelle
Ein alter Thread, den ich kenne, der aber für jeden, der darauf stößt, immer noch sehr relevant ist.
Hier wurde Array.map vorgeschlagen, eine großartige Methode, die ich ständig verwende. Array.reduce wurde auch erwähnt ...
Ich würde persönlich eine Array.reduce für diesen Anwendungsfall verwenden. Warum? Obwohl der Code etwas weniger sauber / klar ist. Es ist viel effizienter als das Weiterleiten der Kartenfunktion an einen Join.
Der Grund dafür ist, dass Array.map jedes Element durchlaufen muss, um ein neues Array mit allen Namen des Objekts im Array zurückzugeben. Array.join durchläuft dann den Inhalt des Arrays, um den Join auszuführen.
Sie können die Lesbarkeit von Jackweirdys verbessern, indem Sie Vorlagenliterale verwenden, um den Code in eine einzelne Zeile zu bringen. "Wird auch in allen modernen Browsern unterstützt"
quelle
Ich bin mir nicht sicher, aber all dies antwortet, obwohl sie funktionieren, aber nicht optiomal sind, da sie zwei Scans durchführen und Sie dies in einem einzigen Scan durchführen können. Obwohl O (2n) als O (n) betrachtet wird, ist es immer besser, ein wahres O (n) zu haben.
Das mag wie in der alten Schule aussehen, aber ich kann es so machen:
quelle
Versuche dies
quelle
name
Attribut fest codiert haben. (a[i].name
verwendet nicht dasname
Argument Ihrer Funktion , es ist äquivalent zua[i]['name']
.)