How to iterate over the keys and values in an object in CoffeeScript?

I have an object (an "associate array" so to say - also known as a plain JavaScript object):

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

I want to iterate over obj using CoffeeScript as follows:

# CS
for elem in obj

bu the CS code above compiles to JS:

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

which isn't appropriate in this case.


The JavaScript way would be for(var key in obj) but now I'm wondering: how can I do this in CoffeeScript?


Solution 1:

Use for x,y of L. Relevant documentation.

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

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

Outputs

jim is 12
john is 7

You may also want to consider the variant for own k,v of ages as mentioned by Aaron Dufour in the comments. This adds a check to exclude properties inherited from the prototype, which is probably not an issue in this example but may be if you are building on top of other stuff.

Solution 2:

You're initializing an array, but then you're using it like an object (there is no "associative array" in js).

Use the syntax for iterating over objects (something like):

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

Solution 3:

The short hand version using array comprehension, which can be used as a one-line loop.

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

Array comprehension are:

"Comprehensions replace (and compile into) for loops, with optional guard clauses and the value of the current array index. Unlike for loops, array comprehensions are expressions, and can be returned and assigned.", http://coffeescript.org/#loops

Solution 4:

with your convention, arr is an array, but "foo" is a property of this array, it is not an indexed value. If you want to store your data the indexed values of an array, you should have written :

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

or if you want an associative array, just use an object :

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

if you want to loop over arr1 :

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

returns :

values are : Bar | Foo |

and to loop over arr2 : "for value in array"

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

which returns :

Foo : Bar
Bar : Foo