From: William James Date: 2005-08-30T14:51:23+09:00 Subject: Re: how to unflatten a flat-array agemoagemo@yahoo.com wrote: > --- Robert Klemme wrote: > > ?> %w{aa bb cc dd ee ff gg hh ii jj > > kk}.each_window(3) {|*a| p a} > > ["aa", "bb", "cc"] > > ["bb", "cc", "dd"] > > ["cc", "dd", "ee"] > > ["dd", "ee", "ff"] > > ["ee", "ff", "gg"] > > ["ff", "gg", "hh"] > > ["gg", "hh", "ii"] > > ["hh", "ii", "jj"] > > ["ii", "jj", "kk"] > > => ["aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", > > "ii", "jj", "kk"] > > Am I the only one who thinks this seems a little > peculiar? > > If I were writing something using this sort of > functionality, I think I'd need and expect > output something like: > > [nil, "aa", "bb"] > ["aa", "bb", "cc"] > ["bb", "cc", "dd"] > ["cc", "dd", "ee"] > ["dd", "ee", "ff"] > ["ee", "ff", "gg"] > ["ff", "gg", "hh"] > ["gg", "hh", "ii"] > ["hh", "ii", "jj"] > ["ii", "jj", "kk"] > ["jj", "kk", nil] > > Admittedly, it'd be hard to that reasonably with a > variable-size window of even length. But for a > previous-current-next arrangement, it seems to make > more sense to say "there is no previous" with a nil > than to basically skip the first item. module Enumerable def each_with_neighbors wind = [nil] each do |x| wind << x wind.shift if wind.size > 3 yield *wind if wind.size == 3 end wind << nil yield *wind[-3,3] if wind.size > 2 self end end %w{aa bb cc dd ee ff gg hh ii jj kk}.each_with_neighbors {|*a| p a} --> [nil, "aa", "bb"] ["aa", "bb", "cc"] ["bb", "cc", "dd"] ["cc", "dd", "ee"] ["dd", "ee", "ff"] ["ee", "ff", "gg"] ["ff", "gg", "hh"] ["gg", "hh", "ii"] ["hh", "ii", "jj"] ["ii", "jj", "kk"] ["jj", "kk", nil]