CoffeeScript zip

Four different solutions to the same problem using CoffeeScript, a for comprehension, and zip. My favorite? I'll go with either #1 because it is the most native to CoffeeScript, and syntactically pleasing, or with #4 because it closely matches the way I think about the solution.

by Alessandro Vernet

HTML

<script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<ol id="result"></ol>

<script type="text/coffeescript">

    # Given this list, we want to compute a list of numbers that would
    # be "between" the numbers in the list, and would be equal to the sum of
    # previous an following number in the original list.    
    l = [1, 2, 3]
    
    l.push 0; l.unshift 0
    l1 = l[0...l.length - 1]
    l2 = l[1...l.length]

    rs = []
        
    # 1. The most native solution
    rs.push((a + b for [a, b] in _.zip l1, l2))
    
    # 2. Using `do` to move the action after the `for`
    rs.push(for [a, b] in _.zip l1, l2 then do () -> a + b)
    
    # 3. Using Underscore's map instead of `for`
    rs.push(_.map (_.zip l1, l2), ([a, b]) -> a + b)
    
    # 4. Trying to be Scala-like, progressively building the result
    rs.push(_(_.zip l1, l2).map ([a, b]) -> a + b)
    
    li = (t) -> $("<li/>").text(t)
    append = (n) -> $("#result").append(n)
    append li r.toString() for r in rs
    
</script>