On Sat, Nov 16, 2002 at 09:30:12PM +0900, Florian Frank wrote: > > I notice that you've made this a method of Enumerable, rather than > > Array. > > I just needed the each iterator, so Array would perhaps be to > restrictive. This way its possible to iterate over a tree of objects for > example if it includes Enumerable. You also needed the #[] method, that's why... > > "abcde".zip > ==>[[97], [98], [99], [100], [101]] > > The index of a string is a number. This only works because numbers > happen to have a "size" method. This nice property doesn't hold for your > example either: ...and.... > You can get strange results if you use "\n" in a string because "each" > iterates over the lines of a string: > > "abcdef\nABCDEFG".zip > ==>[[97, 65], [98, 66], [99, 67], [100, 68], [101, 69], [102, 70], [10, 71]] Tried that with hashes already? :-) For zip to work as an Enumerable's method, you have to rely on #each only. Just use Enumerable#to_a and you'll have the elements like #each would have passed them to you. module Enumerable def zip(*enumerables) zipped = [] # was like this: # all = [self, *enumerables] # now is: all = [self.to_a, *enumerables.collect {|e| e.to_a}] max_length = all.collect {|a| a.length}.max 0.upto(max_length-1) do |i| zipped << all.collect {|a| a[i]} end zipped end end p [1, 2, 3].zip([4, 5, 6]) #=> [[1, 4], [2, 5], [3, 6]] p "one\ntwo\n".zip("three\nfour\n") #=> [["one\n", "three\n"], ["two\n", "four\n"]] h = {:one => "two"} p h.zip({:three => "four"}) #=> [[[:one, "two"], [:three, "four"]]] You needn't obey String#each default blindly, either: $/ = 'o' p "one\ntwo\n".zip("three\nfour\n") #=> [["o", "three\nfo"], ["ne\ntwo", "ur\n"], ["\n", nil]] Massimiliano