From: Robert Klemme Date: 2004-03-20T00:34:33+09:00 Subject: Re: Can I stop each's iteration, and get the results so far? "Sam Roberts" schrieb im Newsbeitrag news:20040319143738.GD7332@certicom.com... > Wrote Robert Klemme , on Fri, Mar 19, 2004 at 05:59:36PM +0900: > > > Basically, I want to break from a find_all, and get the array of > > > elements found so far. Is this possible? > > > > > > I tried this, no luck with find_all and collect, they return nil, > > > instead of the array so far. Any suggestions on how to do this? > > > > #inject is your friend: > > > > > puts "all n between 100 and 200?" > > > > > > p every.find_all { |n| break if n > 200; n >= 100 && n <= 200 } > > > > irb(main):076:0> every.inject([]) { |arr,n| break arr if n > 200; arr< > if n >= 100 && n <= 200; arr } > > => [102, 105, 108, 111, 114, 117, 120, 123, 126, 129, 132, 135, 138, 141, > > 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, > > 189, 192, 195, 198] > > Thanks, thats useful to know, and odd! > > Why can you break from inject and get the result, but not from find_all > or collect? > > Is this a bug, an oversight, or is something about the methods that > makes them need to be different? The difference is that in the inject version you have access to the array that collects values and hence can transmit it to the caller via "break arr". The find_all version has no access to the array and thus you can't return the array via "break". I'm not sure whether "find_all" cannot be implemented differently because I don't know whether find_all can determine whether there was an argument to "break" or not. Because if there was then that is clearly what you want to be returned: irb(main):006:0> (1..10).find_all {|x| break "early exit" if x % 2 == 0} => "early exit" irb(main):007:0> (1..10).find_all {|x| break "early exit" if x % 26666 == 0} => [] Of course you can achieve the same without "inject" by using "return" in a method: def test(enum) arr=[] enum.each { |n| return arr if n > 200; arr<= 100 && n <= 200 } arr end Although I have to admit that I find "inject" more beatiful... :-) Kind regards robert