From: timr Date: 2010-08-28T04:12:29+09:00 Subject: Re: how about Array#collect_until Thanks everyone for the great ideas. I ended up slightly modifying Senault's suggestion (see below), though I learned from all the various approaches. In my particular case I do need an inclusive collect (long story, but using this to do some DNA fuzzy expression matching that smartly knows when it has found a good solution and breaks rather than finishing all the other possible calculations, and I need to see the solution). And though the inject is a great suggestion, I would prefer keeping the code blocks for determining endpoint grammatically separated from the processing block, rather than embedded. Arigato Ruby Community, Tim #collects items processed through block until a solution satisfies the function test (lambda{}) class Array def collect_until(fn, &block) results = [] self.each do |x| result = (yield x) results << result break if fn.call(result) end results end end p %w[ find out if that this but not the other mother mouth].collect_until(lambda {|word| word[-2,2] == 'st' }){|item| item + "t" } puts "another attempt" p [1,6,7,5,3,0,10,12,14].collect_until(Proc.new {|num| num > 25 }){| item| item * 4 } puts "another attempt" p [1,2,3].collect_until(Proc.new {|x| x%2 == 0}) {|item| item + 10} On Aug 27, 1:47 am, "F. Senault" wrote: > Le 27 août à 08:29, timr a écrit : > > > [1,2,3].collect{|item| item + 10} # => [11,12,13] > > [1,2,3].collect_until({|x| x%2 == 0}) {|item| item + 10} # => [11,12] > > Why not something like this : > > class Array >   defcollect_until >     n = [] >     self.each do |e| >       r, brk = yield e >       n << r >       break if brk >     end >     n >   end > end > > Used like this : > > >> [1,2,3].collect_until{ |x| [ x + 10 , (x % 2 == 0) ] } > > => [11, 12] > > Not very pretty, but it does the job. > > Fred > -- > Actual dialogue from the end of the battle: > Cleric:  "Keep hitting it!" > Paladin: "It's dead." > Fighter: "Yeah, but it's not dead enough."  (David P. Murphy in the SDM)