Programming Ruby: The Pragmatic Programmer's Guide

# Programming Ruby ### The Pragmatic Programmer's Guide
Previous < | Contents ^ | Next >

module Enumerable |
Relies on: | each, <=>

### Index:

collect detect each_with_index entries find find_all grep include? map max member? min reject select sort to_a

The `Enumerable` mixin provides collection classes with several traversal and searching methods, and with the ability to sort. The class must provide a method `each`, which yields successive members of the collection. If `Enumerable#max` , `#min`, or `#sort` is used, the objects in the collection must also implement a meaningful `<=>` operator, as these methods rely on an ordering between members of the collection.

instance methods
collect | enumObj.collect {| obj | block } -> anArray
|  | Returns a new array with the results of running block once for every element in enumObj.
`(1..4).collect {|i| i*i }` | » | `[1, 4, 9, 16]`
`(1..4).collect { "cat" }` | » | `["cat", "cat", "cat", "cat"]`
detect | enumObj.detect {| obj | block } -> anObject or `nil`
|  | Passes each entry in enumObj to block. Returns the first for which block is not `false`. Returns `nil` if no object matches.
`(1..10).detect {|i| i % 5 == 0 and i % 7 == 0 }` | » | `nil`
`(1..100).detect {|i| i % 5 == 0 and i % 7 == 0 }` | » | `35`
each_with_index | enumObj.each_with_index {| obj, i | block } -> `nil`
|  | Calls block with two arguments, the item and its index, for each item in enumObj.
`hash = Hash.new`
`%w(cat dog wombat).each_with_index {|item, index|`
`hash[item] = index`
`}`
`hash` | » | `{"cat"=>0, "wombat"=>2, "dog"=>1}`
entries | enumObj.entries -> anArray
|  | Synonym for `Enumerable#to_a` .
find | enumObj.find {| obj | block } -> anObject or `nil`
|  | Synonym for `Enumerable#detect` .
find_all | enumObj.find_all {| obj | block } -> anArray
|  | Returns an array containing all elements of enumObj for which block is not `false` (see also `Enumerable#reject` ).
`(1..10).find_all {|i| i % 3 == 0 }` | » | `[3, 6, 9]`
grep | enumObj.grep( pattern ) -> anArray enumObj.grep( pattern ) {| obj | block } -> anArray
|  | Returns an array of every element in enumObj for which `Pattern === element`. If the optional block is supplied, each matching element is passed to it, and the block's result is stored in the output array.
`(1..100).grep 38..44` | » | `[38, 39, 40, 41, 42, 43, 44]`
`c = IO.constants`
`c.grep(/SEEK/)` | » | `["SEEK_END", "SEEK_CUR", "SEEK_SET"]`
`res = c.grep(/SEEK/) {|v| IO.const_get(v) }`
`res` | » | `[2, 1, 0]`
include? | enumObj.include?( anObject ) -> `true` or `false`
|  | Returns `true` if any member of enumObj equals anObject. Equality is tested using `==`.
`IO.constants.include? "SEEK_SET"` | » | `true`
`IO.constants.include? "SEEK_NO_FURTHER"` | » | `false`
map | enumObj.map {| obj | block } -> anArray
|  | Synonym for `Enumerable#collect` .
max | enumObj.max -> anObject enumObj.max {| a,b | block } -> anObject
|  | Returns the object in enumObj with the maximum value. The first form assumes all objects implement `Comparable`; the second uses the block to return a <=> b.
`a = %w(albatross dog horse)`
`a.max` | » | `"horse"`
`a.max {|a,b| a.length <=> b.length }` | » | `"albatross"`
member? | enumObj.member?( anObject ) -> `true` or `false`
|  | Synonym for `Enumerable#include?` .
min | enumObj.min -> anObject enumObj.min {| a,b | block } -> anObject
|  | Returns the object in enumObj with the minimum value. The first form assumes all objects implement `Comparable`; the second uses the block to return a <=> b.
`a = %w(albatross dog horse)`
`a.min` | » | `"albatross"`
`a.min {|a,b| a.length <=> b.length }` | » | `"dog"`
reject | enumObj.reject {| obj | block } -> anArray
|  | Returns an array for all elements of enumObj for which block is `false` (see also `Enumerable#find_all` ).
`(1..10).reject {|i| i % 3 == 0 }` | » | `[1, 2, 4, 5, 7, 8, 10]`
select | enumObj.select {| obj | block } -> anArray
|  | Synonym for `Enumerable#find_all` .
sort | enumObj.sort -> anArray enumObj.sort {| a, b | block } -> anArray
|  | Returns an array containing the items in enumObj sorted, either according to their own `<=>` method, or by using the results of the supplied block. The block should return -1, 0, or +1 depending on the comparison between a and b.
`%w(rhea kea flea).sort` | » | `["flea", "kea", "rhea"]`
`(1..10).sort {|a,b| b <=> a}` | » | `[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]`
The following code sorts some files on modification time.
`files = Dir["*"]`
`sorted = files.sort {|a,b| File.new(a).mtime <=> File.new(b).mtime}`
`sorted` | » | `["mon", "tues", "wed", "thurs"]`
This sort is inefficient: it generates two new `File` objects during every comparison. A slightly better technique is to use the `Kernel#test` method to generate the modification times directly.
`files = Dir["*"]`
`sorted = files.sort { |a,b|`
`test(?M, a) <=> test(?M, b)`
`}`
`sorted` | » | `["mon", "tues", "wed", "thurs"]`
This still generates many unnecessary `Time` objects. A more efficient technique is to cache the sort keys (modification times in this case) before the sort. Perl users often call this approach a Schwartzian Transform, after Randal Schwartz. We construct a temporary array, where each element is an array containing our sort key along with the filename. We sort this array, and then extract the filename from the result.
`sorted = Dir["*"].collect { |f|`
`[test(?M, f), f]`
`}.sort.collect { |f| f[1] }`
`sorted` | » | `["mon", "tues", "wed", "thurs"]`
to_a | enumObj.to_a -> anArray
|  | Returns an array containing the items in enumObj.
`(1..7).to_a` | » | `[1, 2, 3, 4, 5, 6, 7]`
`{ 'a'=>1, 'b'=>2, 'c'=>3 }.to_a` | » | `[["a", 1], ["b", 2], ["c", 3]]`

Previous < | Contents ^ | Next >

Extracted from the book "Programming Ruby - The Pragmatic Programmer's Guide"
Copyright © 2001 by Addison Wesley Longman, Inc. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at http://www.opencontent.org/openpub/)).

Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder.

Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.