From: Massimiliano Mirra Date: 2002-11-17T19:16:30+09:00 Subject: Re: ruby-dev summary 18613-18710 On Sun, Nov 17, 2002 at 05:18:40AM +0900, Florian Frank wrote: > > Tried that with hashes already? :-) > > I just did: > > h = Hash[*(1..10)] > ==>{5=>6, 1=>2, 7=>8, 3=>4, 9=>10} > h.zip > ==>[[5, 1, 7, 3, 9], [6, 2, 8, 4, 10]] > h.zip == [h.keys, h.values] > ==>true That's because you happen to have numeric keys. Try with {:one => 'two', :three => 'four'}. > In Haskell its only possible to zip two or three "lists" with the > standard library functions. (Just curious: why?) > There is a difference between the collection of "lists" and the > "lists". Sorry I don't understand what you mean. :-( > > 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 > > That's another possibility. The construction of "all" wastes a lot of > memory in some cases, True. That's why I called it `a quick hack' in another thread. > but it is perhaps more flexible because the > arguments only have to be enumerables. I don't know what happens more > often that an object can #[] or includes Enumerable and/or can #each. > If it can't #[] you can always do #to_a to them before using zip. You're assuming that #[](n) returns the element of a collection. While this is often so, there's no assurance. Strings and hashes are the most notable cases. I'd say, rely on enumerables instead. > > You needn't obey String#each default blindly, either: > > > > $/ = 'o' > > You can't shock me -- I confess: I'm a perl programmer. *g* LOL Well, confession heard, my son, now you can repent... (just kidding) > > p "one\ntwo\n".zip("three\nfour\n") > > #=> [["o", "three\nfo"], ["ne\ntwo", "ur\n"], ["\n", nil]] > > To pass another iterator has perhaps an advantage, this comes to my > mind: > > tree.zip(:preorder) > tree.zip(:inorder) > tree.zip(:postorder) Cool. Maybe, since each gets extra parameters already in String, one could also have Tree#each(order), where order can be any of the above three, and zip would just forward the parameter to #each. Massimiliano