Gordon Miller (gmiller / promisemark.com) wrote: > Doing numerically oriented algorithms I find myself frequently doing > something like the following: > > z = (1..5).to_a > a = (0..5).to_a > b = (0..5).to_a > c = z.collect_with_index { |el, i| f(el, a[i], b[i]) } > > something along the lines of a zip... > > c = zip (z, a, b).collect { |el| f(el[0], el[1], el[2]) } I'm also always amazed by the uses of inject. The collect_with_index could be done: c = z.inject( [] ) { |arr, el| arr << f( el, a[arr.length], b[arr.length] ) } Actually, I think an each_with_index equivalent is kinda neat with inject, as you can explicitly set the first index: arr = [] z.inject( 0 ) { |i, el| arr[i] = f(el, a[i], b[i]) i + 1 } It would be really cool if, instead of having a million *_with_index methods floating around in Enumerable, we had a method which could be used inside a block to retrieve the number of iterations that the block has undergone. For instance: class Array def collect( &e ) ary = [] i = 0 self.each { |item| eval( "def index; #{i} end", e ) ary.push( e.call( item ) ) i += 1 } return ary end end The `index' method can then be used in the block: c = z.collect { |el| f(el, a[index], b[index]) } This implementation is flawed, though, because it creates the `index' method in whatever namespace the block is originally placed. But, you know.. what if?? _why