I know you already got something that works, but I think this is a
problem where enumerators provide an elegant solution:
module Enumerable
def through
Enumerator.new do |yielder|
self.each do |val|
yielder.yield(val)
break if yield val
end
end
end
end
then:
[1,2,3].through {|x| x % 2 == 0}.collect {|item| item+10} => [11,12]
Thanks for another useful answer.
I need to read the doc for Enumerator class since I don't really know
how to use it, but your solution appears to run each item into the
first block, until it finds an item producing a true result and then
everything up to that point is sent on to a collect statement for
processing in the second block. I am sure this is going to be useful
in many cases, but it is different from what I was intending for the
collect_until function. You will see how our two solutions differ if
you look at the test cases and the results below.
%w[ find out if that this but not the other mother
mouth].collect_until(lambda {|word| word[-2,2] == 'st' }){|item| item
+ "t" } # => ["findt", "outt", "ift", "thatt", "thist"]
[1,6,7,5,3,0,10,12,14].collect_until(Proc.new {|num| num > 25 }){|
item> item * 4 } # => [4, 24, 28]
[1,2,3].collect_until(Proc.new {|x| x%2 == 0}) {|item| item + 10} # =>
[11, 12]
Versus:
%w[ find out if that this but not the other mother mouth].through {|
word> word[-2,2] == 'st' }.collect{|item| item + "t" } # => ["findt",
"outt", "ift", "thatt", "thist", "butt", "nott", "thet", "othert",
"mothert", "moutht"]
[1,6,7,5,3,0,10,12,14].through {|num| num > 25 }.collect{|item| item *
4 } # => [4, 24, 28, 20, 12, 0, 40, 48, 56]
[1,2,3].through {|x| x%2 == 0}.collect{|item| item + 10} # => [11, 12]