This method has long been suggested to me as #map_detect. At first I
wasn't sure of it's usefulness. But now I think it's okay. (Your
thoughts?). In any case, the name has to go. Currently I'm thinking #find_yield. Any better suggestions?
module Enumerable
# Similar to #detect and #find. Yields each element to the block
# and returns the first result that evaluates as *true*,
# terminating early.
···
#
# obj1.foo? #=> false
# obj2.foo? #=> true
# obj2.foo #=> "value"
#
# [obj1, obj2].find_yield { |obj| obj.foo if obj.foo? } #=>
"value"
#
# If the block is never true, return the +fallback+ parameter,
# or nil if no +fallback+ is specified.
#
# [1,2,3].find_yield { |_| false } #=> nil
# [false].find_yield(1) { |_| false } #=> 1
#
def find_yield(fallback = nil) #:yield:
each do |member|
result = yield(member)
return result if result
end
fallback
end
On Fri, Nov 13, 2009 at 01:07:41AM +0900, Intransition wrote:
This method has long been suggested to me as #map_detect. At first I
wasn't sure of it's usefulness. But now I think it's okay. (Your
thoughts?). In any case, the name has to go. Currently I'm thinking #find_yield. Any better suggestions?
On Thu, Nov 12, 2009 at 9:37 PM, Intransition <transfire@gmail.com> wrote:
This method has long been suggested to me as #map_detect. At first I
wasn't sure of it's usefulness. But now I think it's okay. (Your
thoughts?). In any case, the name has to go. Currently I'm thinking #find_yield. Any better suggestions?
Unless I have misunderstood, I think there is an almost identical
facility built-in:
[1,2,3].find(lambda {-1}) { |x| x > 10 }
=> -1
It's slightly inconvenient to require a proc for the default, but it
means you can create an 'expensive' object or modify the collection with
a side-effect:
I disagree. The difference between TMISFAN (the method in search for a name) and your solution is that TMISFAN returns the result of the block evaluation and not the element contained in the collection.
I don't have frequent use for this but it occurred just a few days ago. This is what I did then - roughly:
x = nil
enum.any? {|e| e > 10 and x = e * 2}
This is dummy code of course, I don't have the concrete example handy. The main point is that #any? will short circuit (like #find) and the special value is reserved via the variable.
How about #find_map? This expresses what happens, first a search and then a mapping of the value - sort of.
Kind regards
robert
···
On 12.11.2009 17:41, Aaron Patterson wrote:
On Fri, Nov 13, 2009 at 01:07:41AM +0900, Intransition wrote:
This method has long been suggested to me as #map_detect. At first I
wasn't sure of it's usefulness. But now I think it's okay. (Your
thoughts?). In any case, the name has to go. Currently I'm thinking #find_yield. Any better suggestions?
I would call the method "unnecessary". Especially since we already have
a built in syntax which is more concise:
Even more concise ...
The only problem I see is if we don't find, we'll call foo on nothing(nil).
So to have the same behavior:
x = [obj1, obj2].find(nil) { |obj| obj.foo? }
x.foo unless foo.nil? #=> "value"
And I think it's quite normal we have to manage with a structure(the if) how
to manage when we didn't find.
But I'm probably missing a special case. Could you give a example in
situation, to see if it is easier to read or not?
If you want to take several objects, you would use [obj1, obj2].select {
obj> obj.foo? }.map {|e| e.foo}
So the idea of Robert Klemme is accurate, sure.
···
2009/11/13 Martin DeMello <martindemello@gmail.com>
On Thu, Nov 12, 2009 at 9:37 PM, Intransition <transfire@gmail.com> wrote:
> This method has long been suggested to me as #map_detect. At first I
> wasn't sure of it's usefulness. But now I think it's okay. (Your
> thoughts?). In any case, the name has to go. Currently I'm thinking
> #find_yield. Any better suggestions?
I agree. But to me #where also conveys the same meaning as #select.
Plus I tend to like it's use in higher-order messaging, and I have no
desire to tread on those toes. However, you did get me thinking in a
different direction which ultimately led me to #found, which conveys
it's relation to #find and that we want, not the element itself, but
what was "found". Though I admit, it has a strange tense for a method
name.
···
On Nov 13, 5:13 am, Martin DeMello <martindeme...@gmail.com> wrote:
On Thu, Nov 12, 2009 at 9:37 PM, Intransition <transf...@gmail.com> wrote:
> This method has long been suggested to me as #map_detect. At first I
> wasn't sure of it's usefulness. But now I think it's okay. (Your
> thoughts?). In any case, the name has to go. Currently I'm thinking
> #find_yield. Any better suggestions?
I think you make a good point. The difference lies in where you are
able to put the logic. Eg.
x = [obj1, obj2].find{ |obj| obj.foo? }
y = x ? do_something_with(x.foo) : nil
vs.
y = [obj1, obj2].find_yield do |obj|
do_something_with(obj.foo) if obj.foo?
end
These are functionally equivalent, so really this is just a matter
constructional preference. If there were a way to make the former more
concise, then the case for the later would probably be moot, but I'm
not sure there is.
···
On Nov 13, 9:12 am, Benoit Daloze <erego...@gmail.com> wrote:
As Aaron,
I prefer the simple built-in method, with what u want to do with the object
after: