Coming from Python, I like many of the features that Coffeescript borrows from Python and Perl (ranges/slices, comprehensions, destructuring assignments). Is there any syntactic sugar in Coffeescript to mimic Python's enumerate
or zip
(itertools.izip
) functions?
Here are the patterns that I don't care much for:
# an enumerate call would be helpful here
i = 0
for x in arr
... use x and i ...
i++
and
# 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 ...
forEach is effectively built in:
a = ['a','b','c']
for el,i in a
alert "Element #{el} is at index #{i}"
Enumerate:
arr.forEach (x, i) ->
... use x and i ...
zip
/ zipWith
(I learned these from Haskell; I assume they mean the same thing in 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
Some examples (tested):
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]
Update: Reimplemented Haskell-style, just for fun. Not as cool without the pattern matching, but oh well..
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
Oh, man, this was fun. SO needs more questions like this :D
Gist for zip
and zipWith
For zipping and other such utility functions, Underscore.js is pretty much the standard library—and it happens to have been created by Jeremy Ashkenas, the man behind CoffeeScript. With it, you could write your zip example as
for elems in _.zip(arr1, arr2)
x = elems[0]; y = elems[1]
...
or better yet
for [x, y] in _.zip(arr1, arr2)
...
using pattern-matching. Note, however, that _.zip
uses the max length of arr1
and arr2
, not the min; so if you don't want to handle undefined
values, you should truncate the longer array first.
There's also a CoffeeScript implementation of Underscore, Underscore.coffee, which is a great place to look if you're wondering how to implement a particular loop in CoffeeScript.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With