<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Global Nerdy &#187; find</title>
	<atom:link href="http://www.globalnerdy.com/tag/find/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.globalnerdy.com</link>
	<description>Tech Evangelist Joey deVilla on software development, tech news and other nerdy stuff</description>
	<lastBuildDate>Fri, 19 Mar 2010 00:24:02 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Enumerating Enumerable: Enumerable#detect/Enumerable#find</title>
		<link>http://www.globalnerdy.com/2008/07/07/enumerating-enumerable-enumerabledetectenumerablefind/</link>
		<comments>http://www.globalnerdy.com/2008/07/07/enumerating-enumerable-enumerabledetectenumerablefind/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 05:02:35 +0000</pubDate>
		<dc:creator>Joey deVilla</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[detect]]></category>
		<category><![CDATA[enumerable]]></category>
		<category><![CDATA[Enumerating Enumerable]]></category>
		<category><![CDATA[find]]></category>
		<category><![CDATA[lambdas]]></category>
		<category><![CDATA[procs]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://globalnerdy.com/?p=1769</guid>
		<description><![CDATA[<p style="text-align:center;"><img src="http://globalnerdy.com/wordpress/wp-content/uploads/2008/06/enumerating_enumerable.jpg" alt="" title="enumerating_enumerable" width="350" height="120" /></p>

<p>Here's another article in the <cite>Enumerating Enumerable</cite> series, in which I attempt to improve upon <a href="http://www.ruby-doc.org/core/classes/Enumerable.html">RubyDoc.org's documentation for the <code>Enumerable</code> module</a>, which I find rather lacking. If you've missed the previous articles in the series, I've listed them below:</p>

<ol>
    <li><a href="http://globalnerdy.com/2008/06/23/enumerating-enumerable-enumerableall/">all?</a></li>
    <li><a href="http://globalnerdy.com/2008/06/24/enumerating-enumerable-enumerableany/">any?</a></li>
    <li><a href="http://globalnerdy.com/2008/06/25/enumerating-enumerable-enumerablecollectenumerablemap/">collect / map</a></li>
    <li><a href="http://globalnerdy.com/2008/07/02/enumerating-enumerable-enumerablecount/">count</a></li>
    <li><a href="http://globalnerdy.com/2008/07/06/enumerating-enumerable-enumerablecycle/">cycle</a></li>
</ol>

<p style="text-align:center;"><a href="http://globalnerdy.com/2008/07/07/enumerating-enumerable-enumerabledetectenumerablefind/"><img src="http://globalnerdy.com/wordpress/wp-content/uploads/2008/07/ruby_enumerabledetect_enumerablefind.jpg" alt="Graphic representation of the \&#34;detect\&#34; or \&#34;find\&#34; method in Ruby\&#039;s \&#34;Enumerable\&#34; module." title="Graphic representation of the \&#34;detect\&#34; or \&#34;find\&#34; method in Ruby\&#039;s \&#34;Enumerable\&#34; module." width="299" height="252" /></a></p>

<p>This installment covers a method that goes by two names: <code>detect</code> or <code>find</code>. I personally prefer <code>find</code>, as it's shorter and the term I tend to use for its function.</p>

<p><a href="http://globalnerdy.com/2008/07/07/enumerating-enumerable-enumerabledetectenumerablefind/"><strong>Read on for more about Enumerable#detect/Enumerable#find...</strong></a></p>]]></description>
			<content:encoded><![CDATA[<p></p><p style="text-align:center;"><img src="http://globalnerdy.com/wordpress/wp-content/uploads/2008/06/enumerating_enumerable.jpg" alt="" title="enumerating_enumerable" width="350" height="120" /></p>
<p>Here&#8217;s another article in the <cite>Enumerating Enumerable</cite> series, in which I attempt to improve upon <a href="http://www.ruby-doc.org/core/classes/Enumerable.html">RubyDoc.org&#8217;s documentation for the <code>Enumerable</code> module</a>, which I find rather lacking. If you&#8217;ve missed the previous articles in the series, I&#8217;ve listed them below:</p>
<ol>
<li><a href="http://globalnerdy.com/2008/06/23/enumerating-enumerable-enumerableall/">all?</a></li>
<li><a href="http://globalnerdy.com/2008/06/24/enumerating-enumerable-enumerableany/">any?</a></li>
<li><a href="http://globalnerdy.com/2008/06/25/enumerating-enumerable-enumerablecollectenumerablemap/">collect / map</a></li>
<li><a href="http://globalnerdy.com/2008/07/02/enumerating-enumerable-enumerablecount/">count</a></li>
<li><a href="http://globalnerdy.com/2008/07/06/enumerating-enumerable-enumerablecycle/">cycle</a></li>
</ol>
<p>This installment covers a method that goes by two names: <code>detect</code> or <code>find</code>. I personally prefer <code>find</code>, as it&#8217;s shorter and the term I tend to use for its function.</p>
<h3>Enumerable#detect/Enumerable#find Quick Summary</h3>
<p style="text-align:center;"><img src="http://globalnerdy.com/wordpress/wp-content/uploads/2008/07/ruby_enumerabledetect_enumerablefind.jpg" alt="Graphic representation of the \&quot;detect\&quot; or \&quot;find\&quot; method in Ruby\&#039;s \&quot;Enumerable\&quot; module." title="Graphic representation of the \&quot;detect\&quot; or \&quot;find\&quot; method in Ruby\&#039;s \&quot;Enumerable\&quot; module." width="299" height="252" /></p>
<table>
<tr>
<th>In the simplest possible terms</th>
<td>What&#8217;s the first item in the collection that meets the given criteria?</td>
</tr>
<tr>
<th>Ruby version</th>
<td>1.8 and 1.9</td>
</tr>
<tr>
<th>Expects</th>
<td>
<ul>
<li>A block containing the criteria.</li>
<li>An optional argument containing a proc that calculates a &#8220;default&#8221; value — that is, the value to return if no item in the collection matches the criteria.</li>
</ul>
</td>
</tr>
<tr>
<th>Returns</th>
<td>The first item in the collection that matches the criteria, if one exists.<br />
If no such item exists in the collection, <code>detect</code>/<code>find</code> returns:
<ul>
<li><code>nil</code> is returned if no argument is provided</li>
<li>the value of the argument, if one is provided.</li>
</ul>
</td>
</tr>
<tr>
<th>RubyDoc.org&#8217;s entry</th>
<td><a href="http://ruby-doc.org/core/classes/Enumerable.html#M001139">Enumerable#detect / Enumerable#find</a></td>
</tr>
</table>
<h3>Enumerable#detect/Enumerable#find and Arrays</h3>
<p>When used on an array without an argument, <code>detect</code>/<code>find</code> passes each item from the collection to the block and&#8230;</p>
<ul>
<li>If the current item causes the block to return a value that doesn&#8217;t evaluate to <code>false</code>, <code>detect</code>/<code>find</code> stops going through collection and returns the item.</li>
<li>If no item in the collection causes the block to return a value that doesn&#8217;t evaluate to <code>false</code>, <code>detect</code>/<code>find</code> returns <code>nil</code>.</li>
</ul>
<p>In the examples that follow, I&#8217;ll be using the <code>find</code> method. <code>detect</code> does exactly the same thing; it&#8217;s just that I prefer <code>find</code>.</p>
<p><code>
<pre>
# Time to establish my "old fart" credentials
classic_rock_bands = ["AC/DC", "Black Sabbath", "Queen", \
"Ted Nugent and the Amboy Dukes", "Scorpions", "Van Halen"]
=> ["AC/DC", "Black Sabbath", "Queen", "Ted Nugent and the Amboy Dukes",
"Scorpions", "Van Halen"]

# Of the bands in the array, which is the first one
# whose name is longer than 8 characters?
classic_rock_bands.find {|band| band.length > 8}
=> "Black Sabbath"

# Which is the first one whose name is exactly
# 5 characters long?
classic_rock_bands.find {|band| band.length == 5}
=> "AC/DC"

# The order of items in the array can affect "find"'s result.
# Let's put the array into reverse sorted order:
classic_rock_bands.sort!.reverse!
=> ["Van Halen", "Ted Nugent and the Amboy Dukes", "Scorpions", \
"Queen", "Black Sabbath", "AC/DC"]

# Again: which is the first band whose name
# is longer than 8 characters?
=> "Van Halen"

# Again: which is the first band whose name
# is exactly 5 characters?
=> "Queen"

# If no band in the array meets the criteria,
# "find" returns nil.
# There are no bands in the list with names shorter
# than 5 characters...
classic_rock_bands.find {|band| band.length < 5}
=> nil
</pre>
<p></code></p>
<p>Using the optional argument is a topic big enough to merit its own section, which appears later in this article.</p>
<h3>Enumerable#detect/Enumerable#find and Hashes</h3>
<p>When used on a hash and a block is provided, <code>detect</code>/<code>find</code> passes each key/value pair in the hash to the block, which you can “catch” as either:</p>
<ol>
<li>A two-element array, with the key as element 0 and its corresponding value as element 1, or</li>
<li>Two separate items, with the key as the first item and its corresponding value as the second item.</li>
</ol>
<p>When used on a hash without an argument, <code>detect</code>/<code>find</code> passes each item from the collection to the block and&#8230;</p>
<ul>
<li>If the current item causes the block to return a value that doesn&#8217;t evaluate to <code>false</code>, <code>detect</code>/<code>find</code> stops going through collection and returns the item.</li>
<li>If no item in the collection causes the block to return a value that doesn&#8217;t evaluate to <code>false</code>, <code>detect</code>/<code>find</code> returns <code>nil</code>.</li>
</ul>
<p><code>
<pre>
years_founded = {"AC/DC" => 1973, \
                 "Black Sabbath" => 1968, \
                 "Queen" => 1970, \
                 "Ted Nugent and the Amboy Dukes" => 1967, \
                 "Scorpions" => 1965, \
                 "Van Halen" => 1972}
# Ruby 1.8 re-orders hashes in some mysterious way that is almost never
# the way you entered it. Here's what I got in Ruby 1.8:
=> {"Queen"=>1970, "AC/DC"=>1973, "Black Sabbath"=>1968, "Scorpions"=>1965,
"Ted Nugent and the Amboy Dukes"=>1967, "Van Halen"=>1972}

# Ruby 1.9 preserves hash order so that hashes keep the order in which
# you defined them. Here's what I got in Ruby 1.9:
=> {"AC/DC"=>1973, "Black Sabbath"=>1968, "Queen"=>1970,
"Ted Nugent and the Amboy Dukes"=>1967, "Scorpions"=>1965, "Van Halen"=>1972}

# Which band is the first in the hash to be founded
# in 1970 or later?
years_founded.find {|band| band[1] >= 1970}
# In Ruby 1.8, the result is:
=> ["Queen", 1970]
# In Ruby 1.9, the result is:
=> ["AC/DC", 1973]

# Here's another way of phrasing it:
years_founded.find {|band, year_founded| year_founded >= 1970}
</pre>
<p></code></p>
<h3>Using Enumerable#detect/Enumerable#find with the Optional Argument</h3>
<p><code>detect</code>/<code>find</code>&#8217;s optional argument lets you specify a proc or lambda whose return value will be the result in cases where no object in the collection matches the criteria.</p>
<p>(Unfortunately, a complete discussion of procs and lambdas is beyond the scope of this article. I highly recommend looking at Eli Bendersky&#8217;s very informative article, <a href="http://eli.thegreenplace.net/2006/04/18/understanding-ruby-blocks-procs-and-methods/"><cite>Understanding Ruby blocks, Procs and methods</cite></a>.)</p>
<p>I think that the optional argument is best explained through examples&#8230;</p>
<p><code>
<pre>
# Once again, the array of classic rock bands
classic_rock_bands = ["AC/DC", "Black Sabbath", "Queen", \
"Ted Nugent and the Amboy Dukes", "Scorpions", "Van Halen"]

# Let's define a proc that will simply returns the band name
# "ABBA", who are most definitely not considered to be
# a classic rock band.
default_band = Proc.new {"ABBA"}

# Procs are objects, so using a proc's name alone isn't sufficient
to invoke its code -- doing so will simply return the proc object.
default_band
=> #&lt;Proc:0x00553f34@(irb):31&gt;
# (The actual value will be different for you, but you get the idea.)

# To call a proc, you have to use its "call" method:
default_band.call
=> "ABBA"

# What we want to do is use "default_band" as a proc that
# provides a default value in the event that detect/find doesn't
# find a value that matches the critera.

# detect/find calls the "call" method of the object you provide
# as the argument if no item in the collection matches the
# criteria in the block.

# There *is* a band in the array that comes after
# "Led Zeppelin" alphabetically: Queen.
classic_rock_bands.find(default_band) {|band| band > "Led Zeppelin"}
=> "Queen"

# The last band in the array, alphabetically speaking,
# is Van Halen. So if we ask detect/find to find a band that
# comes after Van Halen, it won't find one.
# Without the argument, detect/find returns nil,
# but *with* the argument, it will invoke the "call"
# method of the object you provide it.
classic_rock_bands.find(default_band) {|band| band > "Van Halen"}
=> "ABBA"

# Let's try something a little fancier. This time, we'll use a lambda.
# The differences between procs and lambdas are very fine -- I suggest
# you check Eli Bendersky's article for those differences.

# Let's create a lambda that when called,
# returns the name of a randomly-selected pop singer.
random_band = lambda do
    fallback_bands = ["Britney Spears", "Christina Aguilera", "Ashlee Simpson"]
    fallback_bands[rand(fallback_bands.size)]
end

# Let's give it a try...
classic_rock_bands.find(random_band) {|band| band > "Van Halen"}
=> "Britney Spears"

classic_rock_bands.find(random_band) {|band| band > "Van Halen"}
=> "Ashlee Simpson"

classic_rock_bands.find(random_band) {|band| band > "Van Halen"}
=> "Christina Aguilera"

classic_rock_bands.find(random_band) {|band| band > "Led Zeppelin"}
=> "Queen"
</pre>
<p></code></p>
<p>To see a &#8220;real&#8221; application of <code>detect</code>/<code>find's</code> optional argument, see <a href="http://www.rubyquiz.com/quiz77.html">this <cite>Ruby Quiz</cite> problem.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.globalnerdy.com/2008/07/07/enumerating-enumerable-enumerabledetectenumerablefind/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Enumerating Ruby’s &#8220;Enumerable&#8221; Module, Part 3: &#8220;detect&#8221;, a.k.a. &#8220;find&#8221;</title>
		<link>http://www.globalnerdy.com/2008/02/06/enumerating-ruby%e2%80%99s-enumerable-module-part-3-detect-aka-find/</link>
		<comments>http://www.globalnerdy.com/2008/02/06/enumerating-ruby%e2%80%99s-enumerable-module-part-3-detect-aka-find/#comments</comments>
		<pubDate>Thu, 07 Feb 2008 04:59:32 +0000</pubDate>
		<dc:creator>Joey deVilla</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[detect]]></category>
		<category><![CDATA[enumerable]]></category>
		<category><![CDATA[find]]></category>
		<category><![CDATA[methods]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://globalnerdy.com/2008/02/06/enumerating-ruby%e2%80%99s-enumerable-module-part-3-detect-aka-find/</guid>
		<description><![CDATA[<p style="text-align:center;"><a href="http://globalnerdy.com/2008/02/06/enumerating-ruby’s-enumerable-module-part-3-detect-aka-find/"><img src='http://globalnerdy.com/wordpress/wp-content/uploads/2008/02/enumerable_find.jpg' alt='Enumerable#find: A magnifying glass focused on a ruby' width="400" height="300" /></a></p>

Here's the third installment in my series on the method in Ruby's <code>Enumerable</code> module. This one focuses on the <strong>find</strong> method. <a href="http://globalnerdy.com/2008/02/06/enumerating-ruby’s-enumerable-module-part-3-detect-aka-find/"><strong>Read on...</strong></a>]]></description>
			<content:encoded><![CDATA[<p></p><p style="text-align:center;"><img src='http://globalnerdy.com/wordpress/wp-content/uploads/2008/02/enumerable_find.jpg' alt='Enumerable#find: A magnifying glass focused on a ruby' width="400" height="300" /></p>
<p>Welcome to the third installment in my series of articles on the methods of Ruby&#8217;s <code>Enumerable</code> module. This series is meant to address some of the shortcomings in the official documentation</p>
<p>In case you missed the first two, here they are:</p>
<ol>
<li><a href="http://globalnerdy.com/2008/01/29/enumerating-rubys-enumerable-module-part-1-all-and-any/"><code>all?</code> and <code>any?</code></a></li>
<li><a href="http://globalnerdy.com/2008/02/06/enumerating-ruby’s-enumerable-module-part-2-collect-aka-map/"><code>collect</code>/<code>map</code></a></li>
</ol>
<p>In this installment, I&#8217;m going to cover the <code>find</code> method. This is a particularly interesting one because it covers <code>detect</code>/<code>find</code>&#8217;s little-talked about optional parameter.</p>
<h3>detect, a.k.a. find</h3>
<li><strong>In plain language:</strong> What&#8217;s the first item in the collection that meets the given criteria?</li>
<li><strong>Ruby.Doc.org&#8217;s entry:</strong> <a href="http://ruby-doc.org/core/classes/Enumerable.html#M003154"><code>Enumerable#detect</code> / <code>Enumerable#find</code></a></li>
<li><strong>Expects:</strong>
<ul>
<li>A block containing the criteria.</li>
<li>An optional argument containing a proc that calculates a &#8220;default&#8221; value &#8212; that is, the value to return if no item in the collection matches the criteria.</li>
</ul>
</li>
<li><strong>Returns:</strong>
<ul>
<li>The first item in the collection that matches the criteria, if one exists.</li>
<li>If no such item exists in the collection:
<ul>
<li><code>nil</code> if no argument is provided</li>
<li>The value of the argument if one is provided</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><code>detect</code> and <code>find</code> are synonyms &#8212; you can use either. I personally prefer find, as it&#8217;s shorter and a good match with a related method, <code>find_all</code>. I also just think that &#8220;find&#8221; conveys the method&#8217;s functionality much better than &#8220;detect&#8221;.</p>
<h4>Using <code>detect</code>/<code>find</code> with Arrays</h4>
<p>When used on an array without an argument, <code>detect</code>/<code>find</code> passes each item from the collection to the block and&#8230;</p>
<ul>
<li>If the current item causes the block to return a value that doesn&#8217;t evaluate to <code>false</code>, <code>detect</code>/<code>find</code> stops going through collection and returns the item.</li>
<li>If no item in the collection causes the block to return a value that doesn&#8217;t evaluate to <code>false</code>, <code>detect</code>/<code>find</code> returns <code>nil</code>.</li>
</ul>
<p><code>
<pre>
classic_rock_bands = ["AC/DC", "Black Sabbath", "Queen", "Scorpions"]

classic_rock_bands.find {|band| band > "Led Zeppelin"}
=> "Queen"

classic_rock_bands.find {|band| band > "ZZ Top"}
=> nil
</pre>
<p></code></p>
<p>Using the optional argument is a topic big enough to merit its own section, which appears later in this article.</p>
<h4>Using <code>detect</code>/<code>find</code> with Hashes</h4>
<p>With hashes, <code>detect</code>/<code>find</code> passes each key/value pair in the hash to the block, which you can “catch” as either:</p>
<ol>
<li>A two-element array, with the key as element 0 and its corresponding value as element 1, or</li>
<li>Two separate items, with the key as the first item and its corresponding value as the second item.</li>
</ol>
<p><code>detect</code>/<code>find</code> is one of those methods of <code>Enumerable</code> that works a little oddly since:</p>
<ul>
<li>The result it returns depends on the order of the collection</li>
<li>We&#8217;re always told that hashes don&#8217;t really any order (there seems to be one, but it&#8217;s shrouded in mystery).</li>
</ul>
<p><code>
<pre>
metacritic_ratings = {"Juno" => 81, "American Gangster" => 76, \
                      "Golden Compass" => 51, "Meet the Spartans" => 9}
=> {"American Gangster"=>76, "Golden Compass"=>51, "Juno"=>81, "Meet the Spartans"=>9}

metacritic_ratings.find {|metacritic_rating| metacritic_rating[1] > 80}
=> ["Juno", 81]

metacritic_ratings.find {|film, rating| rating > 80}
=> ["Juno", 81]

metacritic_ratings.find {|film, rating| rating > 90}
=> nil
</pre>
<p></code></p>
<h4>Using <code>detect</code>/<code>find</code> with the Optional Argument</h4>
<p><code>detect</code>/<code>find</code>&#8217;s optional argument lets you specify a proc or lambda whose return value will be the result in cases where no object in the collection matches the criteria.</p>
<p>(Unfortunately, a complete discussion of procs and lambdas is beyond the scope of this article. I highly recommend looking at Eli Bendersky&#8217;s very informative article, <a href="http://eli.thegreenplace.net/2006/04/18/understanding-ruby-blocks-procs-and-methods/"><cite>Understanding Ruby blocks, Procs and methods</cite></a>.)</p>
<p>I think that the optional argument is best explained through examples&#8230;</p>
<p><code>
<pre>
classic_rock_bands = ["AC/DC", "Black Sabbath", "Queen", "Scorpions"]

# Let's define a proc that will simply return the default band's name
# for cases where none of the bands in the array meets the criteria.
default_band = Proc.new {"ABBA"}

# Procs are objects, so using a proc's name alone isn't sufficient
to invoke its code -- doing so will simply return the proc object.
default_band
=> #&lt;Proc:0x00553f34@(irb):31&gt;
# (The actual value will be different for you, but you get the idea.)

# To call a proc, you have to use its "call" method:
default_band.call
=> "ABBA"

# detect/find calls the "call" method of the object you provide as the argument
# if no item in the collection matches the criteria in the block.
classic_rock_bands.find(default_band) {|band| band > "Led Zeppelin"}
=> "Queen"

classic_rock_bands.find(default_band) {|band| band > "ZZ Top"}
=> "ABBA"

# Let's try something a little fancier, and use a lambda this time.
# The differences between procs and lambdas are very fine -- I suggest
# you check Eli Bendersky's article for those differences.
random_band = lambda do
	fallback_bands = ["Britney Spears", "Christina Aguilera", "Ashlee Simpson"]
	fallback_bands[rand(fallback_bands.size)]
end

# Let's give it a try...
classic_rock_bands.find(random_band) {|band| band > "ZZ Top"}
=> "Britney Spears"
>> classic_rock_bands.find(random_band) {|band| band > "ZZ Top"}
=> "Ashlee Simpson"
>> classic_rock_bands.find(random_band) {|band| band > "ZZ Top"}
=> "Christina Aguilera"
</pre>
<p></code></p>
<p>To see a &#8220;real&#8221; application of <code>detect</code>/<code>find's</code> optional argument, see <a href="http://www.rubyquiz.com/quiz77.html">this <cite>Ruby Quiz</cite> problem.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.globalnerdy.com/2008/02/06/enumerating-ruby%e2%80%99s-enumerable-module-part-3-detect-aka-find/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
