使用`of`运算符在Coffeescript中迭代ES6 Set/Map

16

如何在Coffeescript中遍历ES6 MapSet

在Javascript中,可以使用以下方法。

s = new Set()
s.add({a: 1})
for (x of s) {
  console.log(x);
}

然而,CoffeeScript 有自己的 "of" 运算符,该运算符会转换为 "in",即:
console.log(x) for x of s

变成 ... for (x in s) { ... }

如何在Coffeescript中访问Javascript的of运算符?

可以通过循环遍历s.values().next()来编写自定义迭代器,但那将是一种败坏行为。 :)


1
我不认为你真的可以。你可以使用高阶函数,而不需要括号来调用,这样几乎和原生语法一样简洁。 - dandavis
1
@dandavis:你的意思是例如 s.forEach(x) -> console.log(x) - Brian M. Hunt
是的,就像那样,你可能需要自己的函数来处理对象/集合输入... - dandavis
1
如何在CoffeeScript中启用Harmony语法支持? - Bergi
3个回答

9

目前还没有办法在coffeescript中使用新的Javascript ES6 of运算符(截至1.9.2版本)。现在最好的选择是使用上面提到的s.forEach (x) -> ...m.forEach (value, key) ->

对于一个集合:

s = new Set
s.add {a: 1}

s.forEach (v) =>
  console.log v

对于一张地图:

m = new Map
m.set {a: 1}, {b: 2}

m.forEach (v, k) =>
  console.log k, v

如果由于某些原因不想创建新的函数,您可以直接使用coffeescript中的迭代器。但这有点棘手。对于集合:

i = s.values()
while(v = i.next(); !v.done)
  console.log v.value

对于一份地图:

i = m.entries()
while(v = i.next(); !v.done)
  [key, value] = v.value
  console.log key, value

在 while 循环中,括号是必要的,以使 while 循环依赖于 v.done。

它们也可以写在一行上,但看起来相当糟糕:

i = s.values(); console.log v.value while(v = i.next(); !v.done)

1
在第一行,你的意思是说“新的JavaScript ES6 **of**运算符”吗? - user663031
1
请注意,of 在迭代器的使用方式上略有不同。它在周围包装了一个隐式的 try finally,以便在循环体提前返回时调用 i.return() - Bergi
是的 - 已经修复了对 of 运算符的引用(谢谢!)。而且,@Bergi 很有趣。 - Joseph
这已经不正确了。你能否编辑一下,加上关于Coffeescript 2.0的说明?http://coffeescript.org/announcing-coffeescript-2/ - Brian M. Hunt

5

Coffeescript 2.0for …from

现在,JavaScript的for...of已经作为CoffeeScript的for ...from(我们已经有了for ...of): for n from generatorFunction()

Coffeescript 1.0 — Backticks

一种选项是使用反引号来嵌入原始的Javascript代码,即http://coffeescript.org/#embedded

`for (x of y) { }`

1
你想要做这样的事情:

eat food for food in ['toast', 'cheese', 'wine']

(其中eat是一个函数)
在您的情况下,您需要执行以下操作:
console.log(x) for x in s

参考: http://coffeescript.org/#loops

使用CoffeeScript REPL非常有帮助。您可以在控制台中输入coffee来打开它。尝试以下代码:

_ = require 'underscore' #substitute underscore for lodash, if you prefer
s = ["a", "b", "c"]
console.log(x) for x in s

编辑:

不幸的是,ES6 中的 Set 功能似乎尚未加入 Coffeescript。考虑使用 underscore 或 lodash 方法 _.unique()_.union() 来模仿您正在寻找的功能。

对于上面的示例:

s = _.unique ["a", "a", "b", "b", "b", "c"]
console.log(x) for x in s

我认为您误读了问题。根据您的示例,需要工作的是 eat food for food in new Set(['toast', 'cheese', 'wine']),但这会失败,因为 CoffeeScript 会将其转换为 for 循环。ES6 集合既没有 length 属性也没有索引。 - Brian M. Hunt
我确实误读了。感谢澄清。看起来集合还没有被引入到Coffeescript中。不过,您可能可以使用underscore或lodash来解决这个问题。请参见我的编辑,如上所述。 - Ashwin Balamohan
感谢@Ashwin - 另一个选项在问题的评论中(s.forEach (x) -> ...)。如果我看到任何进一步阐明的内容,我会发布的。 - Brian M. Hunt
完全没有问题。如果您正在使用纯JS,s.forEach()可以很好地工作,但是在Coffeescript中,s = new Set()会抛出ReferenceError。 - Ashwin Balamohan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接