¿Cómo iterar sobre las claves y los valores en un objeto en CoffeeScript?

190

Tengo un objeto (una "matriz asociada", por así decirlo, también conocido como un objeto JavaScript simple):

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

Quiero repetir objusando CoffeeScript de la siguiente manera:

# CS
for elem in obj

pero el código CS anterior compila a JS:

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

lo cual no es apropiado en este caso.


La forma de JavaScript sería for(var key in obj)pero ahora me pregunto: ¿cómo puedo hacer esto en CoffeeScript?

jhchen
fuente
44
Las "matrices" en JavaScript / CoffeeScript son objetos especiales con índices numéricos y una lengthpropiedad que simplemente se refiere al índice numérico más alto (más 1). Lo que queremos es simplemente un "objeto": obj = {}. Las matrices son objetos, pero no hay razón para usar una en su ejemplo.
Trevor Burnham
1
Buen punto Trevor! He modificado la pregunta para que sea un poco menos engañosa / confusa a este respecto.
Según Lundberg el

Respuestas:

351

Uso for x,y of L. Documentación relevante .

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

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

Salidas

jim is 12
john is 7

También puede considerar la variante for own k,v of agesmencionada por Aaron Dufour en los comentarios. Esto agrega una verificación para excluir las propiedades heredadas del prototipo, lo que probablemente no sea un problema en este ejemplo, pero puede serlo si está construyendo sobre otras cosas.

Mella
fuente
12
Precisamente. CoffeeScript ofcompila a JavaScript in. Es un punto común de confusión, pero tener inque usarlo con matrices es increíblemente útil. Hablo extensamente sobre esto en el libro CoffeeScript .
Trevor Burnham
3
No debe inicializar arrcomo arr = [], debe usar arr = {}. En Javascript (y Coffeescript) las matrices tienen índices numéricos. Los objetos se comportan como matrices / dictos asociativos.
Morgan Harris
Gracias, eso ya lo han señalado Trevor y otros, y mi respuesta se mantuvo en el código de la pregunta original. Actualizaré mi ejemplo para usar un objeto simple para mayor claridad de todos modos.
Nick
13
Aunque no importa para este ejemplo en particular, parece que for own key, value of objestá más cerca de lo que está buscando OP.
Aaron Dufour
4

Estás inicializando una matriz, pero luego la estás utilizando como un objeto (no hay "matriz asociativa" en js).

Use la sintaxis para iterar sobre objetos (algo así como):

for key, val of arr
  console.log key + ': ' + val 
kioopi
fuente
3
En realidad, todos los objetos en JS son matrices asociativas (sin ordenamiento de teclas consistente). Entonces, el código que dio jcmoney debería funcionar, aunque no hay razón para usarlo en []lugar de hacerlo {}en ese caso.
Trevor Burnham
jashkenas.github.com/coffee-script/#loops parece que el bucle generado por coffeescript no iterará sobre los miembros del objeto.
kioopi
3

La versión de mano corta que usa la comprensión de matriz, que puede usarse como un bucle de una línea.

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

La comprensión de la matriz es:

"Las comprensiones reemplazan (y compilan) los bucles, con cláusulas de protección opcionales y el valor del índice de matriz actual. A diferencia de los bucles, las comprensiones de matriz son expresiones y pueden devolverse y asignarse", http://coffeescript.org/ #loops

sqren
fuente
55
por favor explique. simplemente proporcionar un fragmento de código no es suficiente. stackoverflow no es un sitio "dame el codez", la idea es que otros se beneficiarán más si la respuesta proporciona una aclaración del concepto abstracto.
Eliran Malka
1

con su convención, arr es una matriz, pero "foo" es una propiedad de esta matriz, no es un valor indexado. Si desea almacenar sus datos de los valores indexados de una matriz, debería haber escrito:

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

o si quieres una matriz asociativa, solo usa un objeto:

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

si quieres recorrer arr1:

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

devoluciones :

values are : Bar | Foo |

y para recorrer arr2: "para el valor en la matriz"

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

que devuelve:

Foo : Bar
Bar : Foo
Benibur
fuente