RubyGuides
Share this post!

A Basic Guide to The Enumerable Module (+ my favorite method)

What is Enumerable?

Enumerable is a collection of iteration methods, a Ruby module, and a big part of what makes Ruby a great programming language.

Enumerable includes helpful methods like:

  • map
  • select
  • inject

Enumerable methods work by giving them a block.

In that block you tell them what you want to do with every element.

For example:

[1,2,3].map { |n| n * 2 }

Will result on a new array where every number has been doubled.

Exactly what happens depends on what method you use, map helps you transform all the values, select lets you filter a list & inject can be used to add up all the values inside an array.

There are over 20 Enumerable methods, let’s study one in detail.

The Each_Cons Method

My new favorite method is each_cons!

Here’s why:

This method is really useful, you can use it to find n-grams or to check if a sequence of numbers is contiguous when combined with all?, another Enumerable method.

enumerable each_cons

each_cons gives you sub-arrays of size n, so if you have [1,2,3], then each_cons(2) will give you [[1,2], [2,3]].

Let’s see an example:

numbers = [3,5,4,2]

numbers.sort.each_cons(2).all? { |x,y| x == y - 1 }

This code starts by sorting the numbers, then calling each_cons(2), which returns an Enumerator object, and then it calls the all? method to check if all the elements match the condition.

Here is another example, where I use each_cons to check if a character is surrounded by the same character, like this: xyx.

str = 'abcxyx'

str.chars.each_cons(3).any? { |a,b,c| a == c }

There is more!

If you wanted to know how many times this pattern occurs, instead of getting a true / false result, you can just change any? to count.

What I find even more fascinating is the implementation for the each_cons method.

array = []

each do |element|
  array << element
  array.shift     if array.size > n
  yield array.dup if array.size == n
end

Note: This comes from the Rubinius implementation of Enumerable. You can find the original source code here.

The implementation starts with an empty Ruby array, then it iterates through the elements using each.

Everything is pretty standard until here. But then it adds the element to the array and it trims the array (using Array#shift) if the size is bigger than what we want.

The size is the argument to each_cons.

Then it yields a dup of the array if the array has the requested size.

I think this is genius, because it keeps a ‘sliding window’ sort of effect into our enumerable object, instead of having to mess around with array indexes.

More Fascinating Methods

Method Description
count Exactly what the name says, count things that evaluate to true inside a block
group_by Group enumerable elements by the block return value. Returns a hash
partition Partition into two groups. Returns a two-dimensional array
any? Returns true if the block returns true for ANY elements yielded to it
all? Returns true if the block returns true for ALL elements yielded to it
none? Opposite of all?
cycle(n) Repeat ALL the elements n times, so if you do [1,2].cycle(2) you would have [1,2,1,2]
find Like select, but it returns the first thing it finds
inject Accumulates the result of the previous block value & passes it into the next one. Useful for adding up totals
zip Glues together two enumerable objects, so you can work with them in parallel. Useful for comparing elements & for generating hashes
map Transforms every element of the enumerable object & returns the new version as an array

Wrapping Up

As you have seen, Enumerable is a module that is worth mastering, so hop over to the documentation and see what it can do for you!

Don’t forget to share & subscribe to my newsletter in the form below if you enjoyed this article. It would help me a lot! 🙂

4 comments
Serguei Cambour (@belgoros) says 3 years ago

Really helpful article, thank you so much for sharing it, Jesus!!!

    Jesus Castello says 3 years ago

    Thank you for reading 🙂

ttw (@ttwo32) says 3 years ago

Thank you for sharing article. I will read the documentation.

    Jesus Castello says 3 years ago

    There are lots of interesting methods there. Check out the partition method 🙂

Comments are closed