From: Robert Klemme Date: 2006-01-08T03:08:04+09:00 Subject: Re: Iterator Fu Failing Me Bob Hutchison wrote: > On Jan 7, 2006, at 11:13 AM, Robert Klemme wrote: > >> Bob Hutchison wrote: >>> On Jan 6, 2006, at 11:36 PM, James Edward Gray II wrote: >>> >>>> That works. Now can anyone give me a version of the middle section >>>> that doesn't require I call parse?() 50 times? I want something >>>> close to: >>>> >>>> elements = tokens.map do |token| >>>> [ClassA, ClassB, ClassC].find { |kind| kind.parse?(token) } >>>> end >>>> >>>> Except that I want the return result of parse?(), instead of the >>>> class that took it. >>> >>> Why not: >>> >>> elements = tokens.map do |token| >>> result = nil >>> [ClassA, ClassB, ClassC].find { |kind| result = kind.parse? >>> (token) } >>> end >> >> Because this won't return the proper value from the block. You >> need at least to add a line with "result" after the #find. :-) > > cut'n'past-o... oops > >> And then it's much more inelegant than using #detect. :-) > > You mean #detect or #select? #detect - because it stops as soon as it has a hit while #select will return an array. We need just the first hit. >> [nil,nil,nil,"w",2,3].find {|x|puts x;x} nil nil nil w => "w" >> [nil,nil,nil,"w",2,3].select {|x|puts x;x} nil nil nil w 2 3 => ["w", 2, 3] > elements = tokens.select do |token| > result = nil > [ClassA, ClassB, ClassC].find { |kind| results << kind.parse? > (token) } > result > end You don't define results and you never assign result another value than nil... > And this is kind of handy too... > > elements = tokens.map do |token| > result = nil > [ClassA, ClassB, ClassC].find { |kind| result = [token, kind.parse? > (token)] } > result > end There's no point in storing token in result because it's unchanged and available as block parameter. Say what you want, find/detect is the most elegant solution. robert