Як перебрати ключі та значення в об’єкті в CoffeeScript?


190

У мене є об'єкт ("асоційований масив", так би мовити - також відомий як звичайний об'єкт JavaScript):

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

Я хочу повторити objвикористання CoffeeScript наступним чином:

# CS
for elem in obj

bu CS-код вище компілюється в JS:

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

що в цьому випадку не підходить.


Спосіб JavaScript був би, for(var key in obj)але тепер мені цікаво: як це зробити в CoffeeScript?


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це ближче до того, що шукає ОП.
Аарон Дюфур

4

Ви ініціалізуєте масив, але потім використовуєте його як об’єкт (у js немає "асоціативного масиву").

Використовуйте синтаксис для ітерації над об'єктами (щось на зразок):

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

3
Насправді всі об'єкти в JS - це асоціативні масиви (без послідовного упорядкування ключів). Таким чином, код, який надав jcmoney, повинен працювати, хоча немає причини використовувати його []замість {}цього випадку.
Тревор Бернхем

jashkenas.github.com/coffee-script/#loops виглядає так, що цикл, створений coffeescript, не повторюватиметься над об'єктами.
kioopi

3

Коротка версія з використанням розуміння масиву, який може використовуватися як однолінійний цикл.

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

Розуміння масиву:

"Поняття замінюють (і компілюють у) цикли, з необов'язковими захисними застереженнями та значенням поточного індексу масиву. На відміну від циклів, розуміння масивів є виразами, і їх можна повернути та призначити.", Http://coffeescript.org/ #loops


5
Будь ласка, поясніть. просто надання фрагмента коду недостатньо. stackoverflow не є сайтом "дай кодеку", ідея полягає в тому, що інші отримають більше користі, якщо відповідь надасть уточнення абстрактної концепції.
Еліран Малька

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.