Jak iterować klucze i wartości w obiekcie w CoffeeScript?


190

Mam obiekt (że tak powiem „tablicę asocjacyjną” - znany również jako zwykły obiekt JavaScript):

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

Chcę powtórzyć za objpomocą CoffeeScript w następujący sposób:

# CS
for elem in obj

bu powyższy kod CS kompiluje się do JS:

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

co nie jest odpowiednie w tym przypadku.


Sposób na JavaScript byłby taki, for(var key in obj)ale teraz zastanawiam się: jak mogę to zrobić w CoffeeScript?


4
„Tablice” w JavaScript / CoffeeScript to specjalne obiekty z indeksami liczbowymi i lengthwłaściwością, która po prostu odnosi się do najwyższego indeksu liczbowego (plus 1). Co chcesz to tylko „obiekt”: obj = {}. Tablice są obiektami, ale nie ma powodu, aby używać ich w swoim przykładzie.
Trevor Burnham,

1
Dobra uwaga Trevor! Zmodyfikowałem to pytanie, aby było nieco mniej mylące / mylące pod tym względem.
Per Lundberg

Odpowiedzi:


351

Zastosowanie for x,y of L. Odpowiednia dokumentacja .

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

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

Wyjścia

jim is 12
john is 7

Możesz również rozważyć wariant, for own k,v of ageso którym wspomniał Aaron Dufour w komentarzach. Dodaje to zaznaczenie, aby wykluczyć właściwości odziedziczone z prototypu, co prawdopodobnie nie jest problemem w tym przykładzie, ale może być, jeśli budujesz na innych rzeczach.


12
Dokładnie. CoffeeScript ofkompiluje do JavaScript in. Jest to powszechny punkt zamieszania, ale inkorzystanie z tablic jest niezwykle przydatne. Długo o tym mówię w książce CoffeeScript .
Trevor Burnham,

3
Nie należy inicjować, arrponieważ arr = []należy użyć arr = {}. W JavaScript (i Coffeescript) tablice mają indeksy numeryczne. Obiekty zachowują się jak tablice / dykty asocjacyjne.
Morgan Harris

Dzięki, na co zwrócił uwagę Trevor i inni, a moja odpowiedź dotyczyła pierwotnego kodu pytania. Zaktualizuję mój przykład tak, by dla jasności używał zwykłego obiektu.
Nick

13
Chociaż nie ma to znaczenia dla tego konkretnego przykładu, wydaje się, że for own key, value of objjest bliżej tego, czego szuka OP.
Aaron Dufour,

4

Inicjujesz tablicę, ale potem używasz jej jak obiektu (w js nie ma „tablicy asocjacyjnej”).

Użyj iteracji do iteracji po obiektach (coś takiego):

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

3
W rzeczywistości wszystkie obiekty w JS są tablicami asocjacyjnymi (bez spójnego porządkowania kluczy). Tak więc kod podany przez jcmoney powinien działać, chociaż nie ma powodu, aby używać []zamiast {}tego.
Trevor Burnham,

jashkenas.github.com/coffee-script/#loops wygląda na to, że pętla wygenerowana przez coffeescript nie będzie się powtarzać względem elementów obiektu.
kioopi

3

Wersja krótka z wykorzystaniem funkcji tablicowej, która może być używana jako pętla jednowierszowa.

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

Rozumienie tablic to:

„Wyrażenia zastępują (i wkompilowują) pętle z opcjonalnymi klauzulami ochronnymi i wartością bieżącego indeksu tablicy. W przeciwieństwie do pętli, wyrażenia tablicowe są wyrażeniami i można je zwracać i przypisywać.”, Http://coffeescript.org/ #loops


5
proszę wytłumacz. samo podanie fragmentu kodu nie jest wystarczające. stackoverflow nie jest witryną „daj mi kod”, chodzi o to, że inni skorzystają więcej, jeśli odpowiedź wyjaśni wyjaśnienie abstrakcyjnej koncepcji.
Eliran Malka

1

zgodnie z konwencją arr jest tablicą, ale „foo” jest własnością tej tablicy, nie jest wartością indeksowaną. Jeśli chcesz przechowywać swoje dane w indeksowanych wartościach tablicy, powinieneś napisać:

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

lub jeśli chcesz tablicy asocjacyjnej, po prostu użyj obiektu:

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

jeśli chcesz zapętlić arr1:

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

zwroty :

values are : Bar | Foo |

i do zapętlenia arr2: „dla wartości w tablicy”

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

który zwraca:

Foo : Bar
Bar : Foo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.