# Enumerable#detect\_result?

**URL:** <https://www.ruby-forum.com/t/enumerable-detect-result/121180>\
**Category:** Ruby\
**Created:** [November 24, 2007, 11:13pm UTC](https://www.ruby-forum.com/t/enumerable-detect-result/121180 "2007-11-24T23:13:43Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yossef\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/a87d85/32.png) [@Yossef\_M](https://www.ruby-forum.com/u/Yossef_M)\
**Post date:** [November 24, 2007, 11:13pm UTC](https://www.ruby-forum.com/t/enumerable-detect-result/121180/1 "2007-11-24T23:13:43Z")

</div>

Actual code from a recent project:

```
# This is bunk, but I'm tired and can't think of the right way to

```

do this  
# I was trying formats.detect, but that just returns the format,  
not the result  
result = nil  
formats.each do |f|  
result = f.process(mesg)  
break if result  
end

In this context, ‘formats’ is an array of format objects, each of  
which represents a format a message can take. The process method takes  
in a message, checks it against the format object’s configuration, and  
returns either nil (if there was no match) or some useful value.

Thanks to testing, my original concept of

```
formats.detect { |f| f.process(mesg) }

```

was rejected as being wrong. After all, I want the result of the  
process call, not the format object. I could go with collect/detect,  
but knowing I want the first makes that rather pointless, especially  
if processing could be expensive and the array could be long.

Is there anything like Enumerable#detect\_result? Is there any desire  
for it? Is there any better name?

---

<div class="post-metadata">

**Author:** ![Yossef\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/a87d85/32.png) [@Yossef\_M](https://www.ruby-forum.com/u/Yossef_M)\
**Post date:** [November 25, 2007, 12:57am UTC](https://www.ruby-forum.com/t/enumerable-detect-result/121180/2 "2007-11-25T00:57:49Z")

</div>

On Nov 24, 2007 11:12 PM, Yossef M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> end
> 
> ```

hmm yeah I also feel the need for something like map\_first sometimes,  
but there is no such beast.

you can simplify the code above a little bit

formats.each do | f |  
result = …  
break result if result  
end

and if performance is not a problem the following is an alternative

formats.map{ |f| f.process( mesg )}.detect{|x| x}  
if x can never be false that can be written as  
formats.map{ … }.compact.first or use facets  
formats.map\_if{ … }.first if there are possible false values.

I do not know a standard or facets built in method that will stop  
iterating and return the block’s value, hopefully I am wrong 😉

HTH  
Robert

---

<div class="post-metadata">

**Author:** ![Yossef\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/a87d85/32.png) [@Yossef\_M](https://www.ruby-forum.com/u/Yossef_M)\
**Post date:** [November 25, 2007, 4:20am UTC](https://www.ruby-forum.com/t/enumerable-detect-result/121180/3 "2007-11-25T04:20:40Z")

</div>

On Nov 24, 4:12 pm, Yossef M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Is there anything like Enumerable#detect\_result? Is there any desire  
> for it? Is there any better name?

Would this work?

module Enumerable  
def detect\_result(ifnone=nil, &block)  
self.each { |x|  
result = block.call(x)  
return result if result  
}  
if ifnone  
then ifnone.call  
else nil  
end  
end  
end

Regards,  
Jordan

---

<div class="post-metadata">

**Author:** ![Yossef\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/a87d85/32.png) [@Yossef\_M](https://www.ruby-forum.com/u/Yossef_M)\
**Post date:** [November 25, 2007, 7:00am UTC](https://www.ruby-forum.com/t/enumerable-detect-result/121180/4 "2007-11-25T07:00:47Z")

</div>

On Nov 24, 5:12 pm, Yossef M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> end
> 
> ```

A little better.

```
 result = nil
 formats.find do |f|
   result = f.process(mesg)
 end

```

T.

---

<div class="post-metadata">

**Author:** ![Yossef\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/a87d85/32.png) [@Yossef\_M](https://www.ruby-forum.com/u/Yossef_M)\
**Post date:** [November 25, 2007, 10:00am UTC](https://www.ruby-forum.com/t/enumerable-detect-result/121180/5 "2007-11-25T10:00:44Z")

</div>

Yossef,

Just curious, but does the detect\_results method for the Enumerable  
module that I listed above, work for your example:

results = formats.detect\_results { |f| f.process(mesg) }

?

Regards,  
Jordan

---

<div class="post-metadata">

**Author:** ![Yossef\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/a87d85/32.png) [@Yossef\_M](https://www.ruby-forum.com/u/Yossef_M)\
**Post date:** [November 25, 2007, 3:53pm UTC](https://www.ruby-forum.com/t/enumerable-detect-result/121180/6 "2007-11-25T15:53:41Z")

</div>

On Nov 25, 3:00 am, MonkeeSage [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Jordan  
> I didn’t bother to try. It looks like it’ll work just fine. I like the  
> idea of specifying an alternate value if nothing matches, but it’s  
> always odd to pass two blocks to a method.

---

<div class="post-metadata">

**Author:** ![Yossef\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/a87d85/32.png) [@Yossef\_M](https://www.ruby-forum.com/u/Yossef_M)\
**Post date:** [November 25, 2007, 4:16pm UTC](https://www.ruby-forum.com/t/enumerable-detect-result/121180/7 "2007-11-25T16:16:04Z")

</div>

On Nov 25, 8:52 am, Yossef M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I didn’t bother to try. It looks like it’ll work just fine. I like the  
> idea of specifying an alternate value if nothing matches, but it’s  
> always odd to pass two blocks to a method.

It’s actually the same thing that detect() does, I just made it return  
the value of the first True instance, rather than the object. If you  
look at the docs for Enumerable#detect, it’s the same semantics for  
ifnone.

Regards,  
Jordan

---

<div class="post-metadata">

**Author:** ![Yossef\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/a87d85/32.png) [@Yossef\_M](https://www.ruby-forum.com/u/Yossef_M)\
**Post date:** [November 25, 2007, 7:31am UTC](https://www.ruby-forum.com/t/enumerable-detect-result/121180/8 "2007-11-25T07:31:09Z")

</div>

On Nov 25, 12:00 am, Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > ```
> > result = f.process(mesg)
> > 
> > ```
> 
> T.  
> Well, dang. I would say that’s obvious, but if that were actually the  
> case I would’ve thought of it. Nice one.
