Ruby's Enumerable Module

Ruby's enumerable module consists of a number of helpful methods to write tight code when manipulating collections of data like arrays and hashes. Although the formal documentation contains a great overview of all the methods, it can be daunting to sift through which ones are actually useful and how to implement them. 

For beginners, enumerable can also cause confusion because it's almost magical how quickly and concisely complicated outputs and functions are handled. In an effort to clarify use cases, I've outlined below some of the most useful implementations of Enumerable methods. 


Implement with each

To implement enumerable in any Ruby class, you must define a method each that all other enumerable methods will access to iterate over the items in the collection. A simple implementation of this for an instance variable @collection could be: 

class Names 
  include enumerable 
  def each
    @collection.each { |item| yield item }


Enumerable contains quite a few simple boolean methods that only return true or false depending on the conditions of the block passed through the method. These include, .any?, .include?, .none?, and .one?, but the easiest to understand is .all?. 

When using .all?, a method or script will only return true if every single object within the collection satisfies the block's requirements. For example: 

@names = ["Billy", "Bob", "Bono", "Betty"] 

puts @names.all?{ |name| name.start_with? "B"} #=> true


In addition to providing functionality to iterate through an array using a basic each method, the enumerable module has a convenient method called each_with_index that passes through two arguments: the element of the collection and it's index within the collection. 

Below is an example of using an array's index to only print every third letter of the alphabet. 

alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I"]

alphabet.each_with_index do |letter, idx| 
  puts letter if idx % 3 == 2 
#=> C, F, I


Map takes the simple each method to another level by not only iterating through the array and processing a block, but also returning a completely new array of the results. This can prove helpful when you need two versions of a certain data set: both the original and a new modified version. 

Example: return an array of 1 to -100 in descending order. 

puts(1..100).map{ |x| -x }
#=> -1
#=> -2
#=> -3
#=> -100


Inject takes a collection and returns an aggregate value. The simplest and most common implementation of this method is to return a sum of an array, but you can also leverage it to add items into a collection. 

fibonacci = 8.times.inject([0,1]) do |a, idx|
  a << a[-2] + a[-1]

puts fibonacci


Select enables you to pass through a block that evaluates whether something is true or false. It returns only the values within the collection that evaluate to true, making it a simple list sorter.

@numbers = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
#=> 0, 2, 8, 34

For a broader look at all the methods available using Enumerable, you can always just run Enumerable.instance_methods in IRB. 


Special thanks to Ruby Cuts, The Bastards Book of Ruby, Sitepoint for helping my research by distilling all of enumerable's possible implementations into real examples.