On May 1, 2007, at 9:05 AM, Xavier Noria wrote: > On Apr 30, 2007, at 11:13 AM, Xavier Noria wrote: >> On Apr 30, 2007, at 3:43 AM, Rick DeNatale wrote: >>> On 4/28/07, Xavier Noria <fxn / hashref.com> wrote: >>>> This is a possible approach: >>>> >>>> module Enumerable >>>> def each_cycle(window, start=0) >>>> (start...length+start).each do |i| >>>> yield((i..i+window).map {|n| self[n % length]}) >>>> end >>>> end >>>> end >>> >>> This method won't work for Enumerables in general, although I >>> guess it >>> does work for Arrays. >>> >>> Not all enumerables have one or both length or [] methods. >> >> Oh right, thank you. I don't know why ri Enumerable lists length here > > It took me a while to discover where that non-core > Enumerable#length reported by ri/fri comes from, it is defined by > RGL in the file > > rgl-0.2.3/lib/rgl/base.rb > > I've learned that ri offers --system the hard way :-). > > -- fxn For those who aren't reading Rick's blog (where this is now in a comment): module Enumerable def each_cycle(window, start=0) wrap_start = [] cache = [] each_with_index do |e,i| cache << e if i >= start + (window - 1) yield cache[start, window] cache.shift else wrap_start << e end end wrap_start.each do |e| cache << e yield cache[start, window] cache.shift end self end end Then you can each_cycle anything that is Enumerable, like a Range: >> (1..5).each_cycle(3) {|x| p x} [1, 2, 3] [2, 3, 4] [3, 4, 5] [4, 5, 1] [5, 1, 2] => 1..5 >> { 'dog' => 'Rover', 'cat' => 'Mittens', 'fish' => 'Goldie' }.each_cycle(2) {|x| p x} [["cat", "Mittens"], ["fish", "Goldie"]] [["fish", "Goldie"], ["dog", "Rover"]] [["dog", "Rover"], ["cat", "Mittens"]] => {"cat"=>"Mittens", "fish"=>"Goldie", "dog"=>"Rover"} -Rob Rob Biedenharn http://agileconsultingllc.com Rob / AgileConsultingLLC.com