2011-06-20 23 views
178

I tiene un objeto (un "array asociado", también conocido como un objeto Javascript llano):iterar sobre objetos en CoffeeScript

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

y necesito iterar sobre ella usando CoffeeScript. Ahora, haciendo de esta manera:

for elem in obj 

no funciona porque obj.length es 0, que utiliza el código de la compilación js. En Javascript normal, me acaba de hacer

for(var key in obj) 

pero ahora me pregunto: ¿cómo puedo hacer esto en CoffeeScript?

+4

"matrices" en JavaScript/CoffeeScript son objetos especiales con índices numéricos y un 'propiedad length' eso simplemente se refiere al índice numérico más alto (más 1). Lo que quieres es solo un "objeto": 'obj = {}'. Las matrices son objetos, pero no hay razón para usar uno en su ejemplo. –

+1

¡Buen punto, Trevor! He modificado la pregunta para que sea un poco menos engañosa/confusa en este sentido. –

Respuesta

333

Uso for x,y of L. Relevant documentation.

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 es posible que desee considerar la variante for own k,v of ages como se ha mencionado por Aaron Dufour en los comentarios. Esto agrega un control para excluir las propiedades heredadas del prototipo, que probablemente no sea un problema en este ejemplo, pero puede ser si usted está construyendo sobre otras cosas.

+12

Precisamente. El 'de' de CoffeeScript se compila en 'in' de JavaScript. Es un punto común de confusión, pero tener 'in' para usar con arreglos es increíblemente útil. Hablo de esto extensamente en [el libro de CoffeeScript] (http://pragprog.com/titles/tbcoffee/coffeescript). –

+3

No debe inicializar 'arr' como' arr = [] ', debe usar' arr = {} '. En las matrices Javascript (y Coffeescript) tienen índices numéricos. Los objetos se comportan como matrices/dictados asociativos. –

+0

Gracias, eso ya lo señalaron Trevor y otros, y mi respuesta fue mantener el código de pregunta original. Voy a actualizar mi ejemplo para usar un objeto simple para mayor claridad de todos modos. – Nick

4

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

utilizar la sintaxis para iterar sobre los objetos (algo así):

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

En realidad, los objetos * all * en JS son matrices asociativas (sin un orden consistente de claves). Entonces el código jcmoney dio debería funcionar, aunque no hay ninguna razón para usar '[]' en lugar de '{}' en ese caso. –

+0

http://jashkenas.github.com/coffee-script/#loops parece que el bucle generado por coffeescript no iterará sobre los miembros del objeto. – kioopi

2

Versión de mano corta con comprensión de matriz, que se puede utilizar como un bucle de una línea.

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

matriz de comprensión son:.

"de comprensión sustituir (y compilar en) para los bucles, con cláusulas de guardia opcionales y el valor del índice de la matriz actual A diferencia de bucles, comprensiones de matriz son expresiones, y se pueden volver y asignados. ", http://coffeescript.org/#loops

+4

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. –

+2

"puedo hacer la explicación" – makdad

1

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

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

o si desea una matriz asociativa, sólo tiene que utilizar un objeto:

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

si quieres a bucle sobre arr1:

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

devuelve:

values are : Bar | Foo | 

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

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

que devuelve:

Foo : Bar 
Bar : Foo