Wie iteriere ich über die Schlüssel und Werte in einem Objekt in CoffeeScript?

189

Ich habe ein Objekt (sozusagen ein "assoziiertes Array" - auch als einfaches JavaScript-Objekt bekannt):

obj = {}
obj["Foo"] = "Bar"
obj["bar"] = "Foo"

Ich möchte die objVerwendung von CoffeeScript wie folgt wiederholen:

# CS
for elem in obj

bu der obige CS-Code kompiliert zu JS:

// JS
for (i = 0, len = obj.length; i < len; i++)

was in diesem Fall nicht angemessen ist.


Der JavaScript-Weg wäre, for(var key in obj)aber jetzt frage ich mich: Wie kann ich das in CoffeeScript machen?

jhchen
quelle
4
"Arrays" in JavaScript / CoffeeScript sind spezielle Objekte mit numerischen Indizes und einer lengthEigenschaft, die sich einfach auf den höchsten numerischen Index (plus 1) bezieht. Was Sie wollen, ist nur ein "Objekt" : obj = {}. Arrays sind Objekte, aber in Ihrem Beispiel gibt es keinen Grund, eines zu verwenden.
Trevor Burnham
1
Guter Punkt Trevor! Ich habe die Frage so geändert, dass sie in dieser Hinsicht etwas weniger irreführend / verwirrend ist.
Per Lundberg

Antworten:

350

Verwenden Sie for x,y of L. Relevante Dokumentation .

ages = {}
ages["jim"] = 12
ages["john"] = 7

for k,v of ages
  console.log k + " is " + v

Ausgänge

jim is 12
john is 7

Vielleicht möchten Sie auch die for own k,v of agesvon Aaron Dufour in den Kommentaren erwähnte Variante in Betracht ziehen . Dadurch wird eine Überprüfung hinzugefügt, um vom Prototyp geerbte Eigenschaften auszuschließen. Dies ist in diesem Beispiel wahrscheinlich kein Problem, kann jedoch auftreten, wenn Sie auf anderen Elementen aufbauen.

Nick
quelle
12
Genau. CoffeeScript wird ofzu JavaScript kompiliert in. Es ist ein häufiger Punkt der Verwirrung, aber die inVerwendung mit Arrays ist unglaublich nützlich. Ich spreche ausführlich darüber im CoffeeScript-Buch .
Trevor Burnham
3
Sie sollten nicht initialisieren arrals arr = [], Sie sollten verwenden arr = {}. In Javascript (und Coffeescript) haben Arrays numerische Indizes. Objekte verhalten sich wie assoziative Arrays / Dicts.
Morgan Harris
Vielen Dank, darauf haben Trevor und andere bereits hingewiesen, und meine Antwort war, den ursprünglichen Fragencode beizubehalten. Ich werde mein Beispiel aktualisieren, um der Übersichtlichkeit halber ein einfaches Objekt zu verwenden.
Nick
13
Obwohl es für dieses spezielle Beispiel keine Rolle spielt, scheint es for own key, value of objnäher an dem zu sein, wonach OP sucht.
Aaron Dufour
4

Sie initialisieren ein Array, verwenden es dann aber wie ein Objekt (in js gibt es kein "assoziatives Array").

Verwenden Sie die Syntax zum Iterieren über Objekte (so etwas wie):

for key, val of arr
  console.log key + ': ' + val 
Kioopi
quelle
3
Tatsächlich sind alle Objekte in JS assoziative Arrays (ohne konsistente Schlüsselreihenfolge). So ist der Code jcmoney gab funktionieren soll, wenn auch kein Grund zu verwenden , gibt es []statt {}in diesem Fall.
Trevor Burnham
jashkenas.github.com/coffee-script/#loops sieht so aus, als würde die von coffeescript erzeugte Schleife nicht über Objektmitglieder iterieren.
Kioopi
3

Die Kurzhandversion mit Array-Verständnis, die als einzeilige Schleife verwendet werden kann.

console.log index + ": " + elm for index, elm of array

Array-Verständnis sind:

"Verständnisse ersetzen (und kompilieren) for-Schleifen durch optionale Schutzklauseln und den Wert des aktuellen Array-Index. Im Gegensatz zu Schleifen sind Array-Verständnisse Ausdrücke und können zurückgegeben und zugewiesen werden.", Http://coffeescript.org/ #loops

sqren
quelle
5
bitte erkläre. Es reicht nicht aus, nur ein Code-Snippet bereitzustellen. Stackoverflow ist keine "Gimme the Codez" -Seite. Die Idee ist, dass andere mehr davon profitieren, wenn die Antwort eine Klarstellung des abstrakten Konzepts liefert.
Eliran Malka
1

Mit Ihrer Konvention ist arr ein Array, aber "foo" ist eine Eigenschaft dieses Arrays, es ist kein indizierter Wert. Wenn Sie Ihre Daten in den indizierten Werten eines Arrays speichern möchten, sollten Sie Folgendes geschrieben haben:

arr1 = []
arr1[0] = "Bar"
arr1[1] = "Foo"

oder wenn Sie ein assoziatives Array möchten, verwenden Sie einfach ein Objekt:

arr2 = {}
arr2["Foo"] = "Bar" // equivalent to arr2.foo="Bar"
arr2["bar"] = "Foo" // equivalent to arr2.bar="Foo"

Wenn Sie arr1 durchlaufen möchten:

str = "values are : "
for val in arr2
  str += val + " |"
console.log key + ': ' + val

kehrt zurück :

values are : Bar | Foo |

und um arr2 zu durchlaufen: "für Wert im Array"

for key, val of arr
  console.log key + ': ' + val

was zurückgibt:

Foo : Bar
Bar : Foo
Benibur
quelle