在Coffeescript中枚举和压缩?

yon*_*ran 31 list-comprehension coffeescript

来自Python,我喜欢Coffeescript从Python和Perl借用的许多功能(范围/切片,理解,解构分配).Coffeescript中是否存在模仿Python enumeratezip(itertools.izip)函数的语法糖?

以下是我不太关心的模式:

# an enumerate call would be helpful here
i = 0
for x in arr
  ... use x and i ...
  i++
Run Code Online (Sandbox Code Playgroud)

# 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 ...
Run Code Online (Sandbox Code Playgroud)

Mar*_*ith 29

forEach有效内置:

a = ['a','b','c']
for el,i in a
    alert "Element #{el} is at index #{i}"
Run Code Online (Sandbox Code Playgroud)

  • 在我写回答之前,我确实检查了[语言参考](http://CoffeeScript.Org/#loops),但这似乎没有记录,或者更有可能,我没有找到它. (3认同)

Jon*_*ier 13

枚举:

arr.forEach (x, i) ->
    ... use x and i ...
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

一些例子(测试):

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]
Run Code Online (Sandbox Code Playgroud)

更新:重新实现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
Run Code Online (Sandbox Code Playgroud)

哦,伙计,这很有趣.因此需要更多这样的问题:D

要点zipzipWith


Tre*_*ham 8

对于压缩和其他此类实用程序函数,Underscore.js几乎是标准库 - 它恰好是由CoffeeScript背后的人Jeremy Ashkenas创建的.有了它,您可以将您的zip示例编写为

for elems in _.zip(arr1, arr2)
  x = elems[0]; y = elems[1]
  ...
Run Code Online (Sandbox Code Playgroud)

还是更好

for [x, y] in _.zip(arr1, arr2)
  ...
Run Code Online (Sandbox Code Playgroud)

使用模式匹配.但请注意,_.zip使用的最大长度为arr1arr2不是min; 因此,如果您不想处理undefined值,则应首先截断较长的数组.

还有一个实施的CoffeeScript下划线的Underscore.coffee,这是看如果你想知道如何实现在CoffeeScript中特定回路的好地方.


pol*_*lau 5

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]]
Run Code Online (Sandbox Code Playgroud)

http://coffeescriptcookbook.com/chapters/arrays/zip-function