Как перебрать ключи и значения в объекте в CoffeeScript?

190

У меня есть объект (так называемый «ассоциированный массив» - также известный как простой объект JavaScript):

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

Я хочу перебрать objиспользование CoffeeScript следующим образом:

# CS
for elem in obj

Бу код CS выше компилируется в JS:

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

что не подходит в этом случае.


Путь JavaScript был бы, for(var key in obj)но теперь я задаюсь вопросом: как я могу сделать это в CoffeeScript?

jhchen
источник
4
«Массивы» в JavaScript / CoffeeScript - это специальные объекты с числовыми индексами и lengthсвойством, которое просто ссылается на самый высокий числовой индекс (плюс 1). То, что вы хотите, это просто «объект» obj = {}. Массивы - это объекты, но нет причин использовать их в вашем примере.
Тревор Бёрнхем
1
Хороший вопрос, Тревор! Я изменил вопрос, чтобы быть немного менее вводящим в заблуждение / сбивающим с толку в этом отношении.
По Лундбергу

Ответы:

351

Использование for x,y of L. Соответствующая документация .

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

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

Выходы

jim is 12
john is 7

Вы также можете рассмотреть вариант, for own k,v of agesупомянутый Аароном Дюфуром в комментариях. Это добавляет проверку для исключения свойств, унаследованных от прототипа, что, вероятно, не является проблемой в этом примере, но может быть, если вы строите поверх других вещей.

Ник
источник
12
Точно. CoffeeScript ofкомпилируется в JavaScript in. Это общая путаница, но inиспользование с массивами невероятно полезно. Я подробно об этом говорю в книге CoffeeScript .
Тревор Бернхам
3
Вы не должны инициализировать arrкак arr = [], вы должны использовать arr = {}. В Javascript (и Coffeescript) массивы имеют числовые индексы. Объекты ведут себя как ассоциативные массивы / дикты.
Морган Харрис
Спасибо, на это уже указывал Тревор и другие, и мой ответ оставался неизменным. Я обновлю свой пример, чтобы использовать простой объект для ясности в любом случае.
Ник
13
Хотя это не имеет значения для этого конкретного примера, похоже, что for own key, value of objон ближе к тому, что ищет OP.
Аарон Дюфур
4

Вы инициализируете массив, но затем используете его как объект (в js нет «ассоциативного массива»).

Используйте синтаксис для перебора объектов (что-то вроде):

for key, val of arr
  console.log key + ': ' + val 
kioopi
источник
3
На самом деле все объекты в JS являются ассоциативными массивами (без согласованного упорядочения ключей). Таким образом, код, который дал jcmoney, должен работать, хотя и нет причины использовать его []вместо {}этого.
Тревор Бернхем
jashkenas.github.com/coffee-script/#loops выглядит так, будто цикл, сгенерированный coffeescript, не будет перебирать объекты-члены.
Киопи
3

Сокращенная версия, использующая понимание массива, которая может использоваться как однострочный цикл.

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

Массивом понимания являются:

«Понимания заменяют (и компилируют в) циклы с необязательными предложениями защиты и значением текущего индекса массива. В отличие от циклов, массивы понимают как выражения и могут быть возвращены и назначены.», Http://coffeescript.org/ #loops

sqren
источник
5
пожалуйста, объясни. просто предоставление фрагмента кода недостаточно. StackOverflow не является сайтом «gimme the codez», идея состоит в том, что другие получат больше пользы, если ответ даст разъяснение абстрактной концепции.
Элиран Малка
1

согласно вашему соглашению arr - это массив, но «foo» - это свойство этого массива, а не индексированное значение. Если вы хотите сохранить ваши данные в индексированных значениях массива, вы должны написать:

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

или если вы хотите ассоциативный массив, просто используйте объект:

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

если вы хотите перебрать arr1:

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

возвращает:

values are : Bar | Foo |

и зациклить на arr2: "для значения в массиве"

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

который возвращает:

Foo : Bar
Bar : Foo
Benibur
источник