来自Python,我喜欢Coffeescript从Python和Perl借用的许多功能(范围/切片,理解,解构分配)。 Coffeescript中是否存在模仿Python的enumerate
或zip
(itertools.izip
)函数的语法糖?
以下是我不太关心的模式:
# an enumerate call would be helpful here
i = 0
for x in arr
... use x and i ...
i++
和
# a zip would be useful here
n = Math.min(arr1.length,arr2.length)
for i in 0...n
x = arr1[i]; y = arr2[i]
... use x and y ...
答案 0 :(得分:29)
forEach有效内置:
a = ['a','b','c']
for el,i in a
alert "Element #{el} is at index #{i}"
答案 1 :(得分:13)
枚举:
arr.forEach (x, i) ->
... use x and i ...
zip
/ zipWith
(我从Haskell学到了这些;我认为它们在Python中的意思相同?):
zip = (arr1, arr2) ->
basic_zip = (el1, el2) -> [el1, el2]
zipWith basic_zip, arr1, arr2
zipWith = (func, arr1, arr2) ->
min = Math.min arr1.length, arr2.length
ret = []
for i in [0...min]
ret.push func(arr1[i], arr2[i])
ret
一些例子(测试过):
zip([1, 2, 3], [4, 5, 6]) # => [[1, 4], [2, 5], [3, 6]]
add = (el1, el2) -> el1 + el2
zipWith(add, [1, 2, 3], [4, 5, 6]) # => [5, 7, 9]
更新:重新实现Haskell风格,只是为了好玩。没有模式匹配就不那么酷了,但是好吧..
zipWith = (func, arr1, arr2) ->
return [] if arr1.length is 0 or arr2.length is 0
el1 = arr1.shift()
el2 = arr2.shift()
ret_arr = zipWith func, arr1, arr2
ret_arr.unshift func(el1, el2)
ret_arr
哦,伙计,这很有趣。因此需要更多这样的问题:D
答案 2 :(得分:8)
对于压缩和其他此类实用程序函数,Underscore.js几乎是标准库 - 它碰巧是由CoffeeScript背后的人Jeremy Ashkenas创建的。有了它,您可以将您的zip示例编写为
for elems in _.zip(arr1, arr2)
x = elems[0]; y = elems[1]
...
或更好
for [x, y] in _.zip(arr1, arr2)
...
使用模式匹配。但请注意,_.zip
使用arr1
和arr2
的 max 长度,而不是min;因此,如果您不想处理undefined
值,则应首先截断较长的数组。
还有一个下划线的CoffeeScript实现,Underscore.coffee,如果你想知道如何在CoffeeScript中实现一个特定的循环,这是一个很好看的地方。
答案 3 :(得分:5)
The CoffeeScript Cookbook列出了一个很好的zip函数实现:
# Usage: zip(arr1, arr2, arr3, ...)
zip = () ->
lengthArray = (arr.length for arr in arguments)
length = Math.min(lengthArray...)
for i in [0...length]
arr[i] for arr in arguments
zip([0, 1, 2, 3], [0, -1, -2, -3])
# => [[0, 0], [1, -1], [2, -2], [3, -3]]
http://coffeescriptcookbook.com/chapters/arrays/zip-function
答案 4 :(得分:2)
不要忘记CoffeeScript只是ECMAScript的替代语法。至少对于你的第一个例子,有一个非常好的ECMAscript函数(Array.prototype.forEach
),它已经做了你想要的:
arr = ["a", "b", "c"]
arr.forEach (el, i) ->
alert "Element #{el} is at index #{i}"
很遗憾,没有Array.prototype.zip
或Array.prototype.zipWith
。这似乎是一个非常大的遗漏,特别是考虑到reduce
和reduceRight
,后者是许多其他语言所没有的。{1}}和zip
。我的猜测是,这是一个简单的疏忽,我们将在该语言的某个未来版本中看到{{1}}。
答案 5 :(得分:0)
对于zip,试试这个:
zip = (x...) ->
(y[i] for y in x for i in [0...Math.min (y.length for y in x)...])
如果您希望一直拉到最后,请使用Math.max()
。