Como iterar sobre as chaves e os valores em um objeto no CoffeeScript?

189

Eu tenho um objeto (um "array associado", por assim dizer - também conhecido como um objeto JavaScript simples):

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

Quero iterar objusando o CoffeeScript da seguinte maneira:

# CS
for elem in obj

O código CS acima compila para JS:

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

o que não é apropriado neste caso.


A maneira JavaScript seria, for(var key in obj)mas agora estou me perguntando: como posso fazer isso no CoffeeScript?

jhchen
fonte
4
"Matrizes" em JavaScript / CoffeeScript são objetos especiais com índices numéricos e uma lengthpropriedade que simplesmente se refere ao índice numérico mais alto (mais 1). O que você quer é apenas um "objeto": obj = {}. Matrizes são objetos, mas não há razão para usar uma no seu exemplo.
Trevor Burnham
1
Bom ponto Trevor! Modifiquei a questão para ser um pouco menos enganosa / confusa a esse respeito.
Per Lundberg

Respostas:

350

Use for x,y of L. Documentação relevante .

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

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

Saídas

jim is 12
john is 7

Você também pode considerar a variante for own k,v of agesmencionada por Aaron Dufour nos comentários. Isso adiciona uma verificação para excluir propriedades herdadas do protótipo, o que provavelmente não é um problema neste exemplo, mas pode ser se você estiver construindo sobre outras coisas.

usuario
fonte
12
Precisamente. CoffeeScript ofcompila para JavaScript in. É um ponto comum de confusão, mas inusar com matrizes é incrivelmente útil. Eu falo sobre isso longamente no livro CoffeeScript .
Trevor Burnham
3
Você não deve inicializar arrcomo arr = [], você deve usar arr = {}. Em Javascript (e Coffeescript), as matrizes têm índices numéricos. Os objetos se comportam como matrizes / dictos associativos.
Morgan Harris
Obrigado, isso já foi apontado por Trevor e outros, e minha resposta foi manter o código da pergunta original. Vou atualizar meu exemplo para usar um objeto simples para maior clareza.
18713 Nick
13
Embora isso não importe para este exemplo específico, parece que for own key, value of objestá mais próximo do que o OP está procurando.
Aaron Dufour
4

Você está inicializando uma matriz, mas depois a usa como um objeto (não há "matriz associativa" em js).

Use a sintaxe para iterar sobre objetos (algo como):

for key, val of arr
  console.log key + ': ' + val 
kioopi
fonte
3
Na verdade, todos os objetos em JS são matrizes associativas (sem ordenação consistente de chaves). Portanto, o código fornecido pelo jcmoney deve funcionar, embora não haja motivo para usá-lo, em []vez disso {}nesse caso.
Trevor Burnham
jashkenas.github.com/coffee-script/#loops parece que o loop gerado pelo coffeescript não itera sobre os membros do objeto.
precisa saber é o seguinte
3

A versão curta usando compreensão de array, que pode ser usada como um loop de uma linha.

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

A compreensão da matriz é:

"As compreensões substituem (e compilam) por loops, com cláusulas de guarda opcionais e o valor do índice atual da matriz. Diferentemente dos loops, as compreensões da matriz são expressões e podem ser retornadas e atribuídas.", Http://coffeescript.org/ #rotações

sqren
fonte
5
Por favor explique. apenas fornecer um trecho de código não é suficiente. stackoverflow não é um site "dê-me o codez", a idéia é que outros se beneficiarão mais se a resposta fornecer um esclarecimento sobre o conceito abstrato.
Eliran Malka
1

com sua convenção, arr é uma matriz, mas "foo" é uma propriedade dessa matriz, não é um valor indexado. Se você deseja armazenar seus dados com os valores indexados de uma matriz, você deve ter escrito:

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

ou se você deseja uma matriz associativa, basta usar um objeto:

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

se você quiser passar por arr1:

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

retorna:

values are : Bar | Foo |

e fazer um loop sobre arr2: "para valor na matriz"

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

que retorna:

Foo : Bar
Bar : Foo
Benibur
fonte