<?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; methods</title>
	<atom:link href="http://www.globalnerdy.com/tag/methods/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>Wed, 17 Mar 2010 22:41:36 +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 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>
		<item>
		<title>Enumerating Ruby’s &#8220;Enumerable&#8221; Module, Part 2: &#8220;collect&#8221;, a.k.a. &#8220;map&#8221;</title>
		<link>http://www.globalnerdy.com/2008/02/06/enumerating-ruby%e2%80%99s-enumerable-module-part-2-collect-aka-map/</link>
		<comments>http://www.globalnerdy.com/2008/02/06/enumerating-ruby%e2%80%99s-enumerable-module-part-2-collect-aka-map/#comments</comments>
		<pubDate>Wed, 06 Feb 2008 05:32:09 +0000</pubDate>
		<dc:creator>Joey deVilla</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[enumerable]]></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-2-collect-aka-map/</guid>
		<description><![CDATA[<p><a href="http://globalnerdy.com/2008/02/06/enumerating-ruby’s-enumerable-module-part-2-collect-aka-map/"><img src="http://globalnerdy.com/wordpress/wp-content/uploads/2008/01/ruby.thumbnail.jpg" width="110" height="120" alt="Ruby gemstone" align="left" /></a>Here's part 2 of my ongoing series covering the methods in Ruby's <code>Enumerable</code> module -- this one covers the <code>collect</code> method, a.k.a. <code>map</code>.</p>

<p><a href="http://globalnerdy.com/2008/02/06/enumerating-ruby’s-enumerable-module-part-2-collect-aka-map/"><strong>Read on...</strong></a></p>]]></description>
			<content:encoded><![CDATA[<p></p><p><a href="http://globalnerdy.com/2008/01/29/enumerating-rubys-enumerable-module-part-1-all-and-any/">In the last article in this series covering the methods in Ruby&#8217;s <code>Enumerable</code> module</a>, I covered <code>all?</code> and <code>any?</code>. In this installment, I&#8217;ll look at the <code>collect</code> method, a.k.a. the <code>map</code> method.</p>
<h3>collect, a.k.a. map</h3>
<ul>
<li><strong>In plain language:</strong> Create an array by performing some operation on every item in the given collection.</li>
<li><strong>Ruby.Doc.org&#8217;s entry:</strong> <a href="http://www.ruby-doc.org/core/classes/Enumerable.html#M003158"><code>Enumerable#collect</code> / <code>Enumerable#map</code></a></li>
<li><strong>Expects:</strong> A block containing the operation (it&#8217;s optional, but you&#8217;re likely to use one most of the time).</li>
<li><strong>Returns:</strong> An array made up of items created by performing some operation on the given collection.</li>
</ul>
<p><code>collect</code> and <code>map</code> are synonyms &#8212; you can use either. I personally prefer <code>map</code> as it&#8217;s shorter and makes more sense: I view the operation as using a function to map a collection to an array.</p>
<h4>Using <code>collect</code>/<code>map</code> with Arrays</h4>
<p>When used on an array and a block is provided, <code>collect</code>/<code>map</code> passes each item to the block, where the operation in the block is performed on the item and the result is then added to the result array. Note the the result array has the same number of elements as the given array.</p>
<p><code>
<pre>
[1, 2, 3, 4].map {|number| number ** 2}
=> [1, 4, 9, 16]

["Aqua", "Bat", "Super", "Wonder Wo"].map {|adjective| adjective + "man"}
=> ["Aquaman", "Batman", "Superman", "Wonder Woman"]
</pre>
<p></code></p>
<p>When the block is omitted, <code>collect</code>/<code>map</code> uses this implied block: <code>{|item| item}</code>, which means when applied on an array without a block, <code>collect</code>/<code>map</code> is the identity function &#8212; the resulting array is the same as the given array.</p>
<p><code>
<pre>
[1, 2, 3, 4].map
=> [1, 2, 3, 4]

["Aqua", "Bat", "Super", "Wonder Wo"].map
=> ["Aqua", "Bat", "Super", "Wonder Wo"]
</pre>
<p></code></p>
<h4>Using <code>collect</code>/<code>map</code> with Hashes</h4>
<p>When used on a hash and a block is provided, <code>collect</code>/<code>map</code> passes each key/value pair in the hash to the block, which you can &#8220;catch&#8221; 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>Each key/value pair is passed to the block, where the operation in the block is performed on the item and the result is then added to the result array. Note the the result array has the same number of elements as the given array.</p>
<p><code>
<pre>
burgers = {"Big Mac" => 300, "Whopper with cheese" => 450, "Wendy's Double with cheese" => 320}

# What if I had just half a burger?
burgers.map {|burger| burger[1] / 2}
=> [160, 150, 225]

burgers.map {|sandwich, calories| calories / 2}
=> [160, 150, 225]

burgers.map {|burger| "Have a tasty #{burger[0]}!"}
=> ["Have a tasty Wendy's Double with cheese!", "Have a tasty Big Mac!", "Have a tasty Whopper with cheese!"]

burgers.map {|sandwich, calories| "Have a tasty #{sandwich}!"}
=> ["Have a tasty Wendy's Double with cheese!", "Have a tasty Big Mac!", "Have a tasty Whopper with cheese!"]

burgers.map {|sandwich, calories| ["Half a #{sandwich}", calories / 2]}
=> [["Half a Wendy's Double with cheese", 160], ["Half a Big Mac", 150], ["Half a Whopper with cheese", 225]]
</pre>
<p></code></p>
<p>When the block is omitted, <code>collect</code>/<code>map</code> uses this implied block: <code>{|item| item}</code>, which means when applied on an hash without a block, <code>collect</code>/<code>map</code> returns an array containing a set of two-item arrays, one for each key/value pair in the hash. For each two-item array, item 0 is the key and item 1 is the corresponding value.</p>
<p><code>
<pre>
burgers = {"Big Mac" => 300, "Whopper with cheese" => 450, "Wendy's Double with cheese" => 320}

burgers.map
=> [["Wendy's Double with cheese", 320], ["Big Mac", 300], ["Whopper with cheese", 450]]
</pre>
<p></code></p>
<h4>Special Case: Using <code>collect</code>/<code>map</code> on Empty Arrays and Hashes</h4>
<p>When applied to an empty array or hash, with or without a block, <code>all?</code> always returns <code>true</code>.</p>
<p><code>
<pre>
[].map
=> []

[].map {|item| item * 2}
=> []

{}.map
=> []

{}.map {|sandwich, calories| "Have a tasty #{sandwich}!"}
=> []
</pre>
<p></code></p>
<h3>In the Next Installment&#8230;</h3>
<p>&#8230;the <code>detect</code> (a.k.a. <code>find</code>) method.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.globalnerdy.com/2008/02/06/enumerating-ruby%e2%80%99s-enumerable-module-part-2-collect-aka-map/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
