Iteration and Collation

Suppose you have two or more arrays, in Ruby, and need to iterate over them together. Naturally, there are lots of ways to do this.

First, there is the obvious way:

foo = %w{one two three}
bar = %w{A B C}

foo.size.times {|i| do_something foo[i], bar[i]}

Alternatively,

foo = %w{one two three}
bar = %w{A B C}

foo.each_with_index {|number, i| do_something number, bar[i]}

This is reasonable enough. It is efficient, and short to type. On the down side, you can’t use Enumerable with it.

I originally wrote the following code to cleanly get collation with Enumerable support:

foo = %w{one two three}
bar = %w{A B C}

class Collation
include Enumerable

def initialize *arrays
raise 'Must include at least one array' if arrays.empty?
@arrays = arrays
end

def each
@arrays[0].each_with_index do |elt, i|
yield [elt] + @arrays[1..-1].map {|array| array[i]}
end
end
end

Collation.new(foo, bar).each {|number, letter| do_something number, letter}

This isn’t really necessary though. It turns out you can collate just fine using the standard library (and with a C implementation, too):

[foo, bar].transpose.each {|number, letter| do_something number, letter}

The moral of the story? Hmm. How about (1) you can have your cake and eat it too, and (2) odds are very high that there is library support for what you are trying to do. Don’t give up easily on the search for a standard way to do what you are trying to accomplish.