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**:

These methods allow you to filter, transform & group objects.

But my new favorite 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.

`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! ðŸ™‚

*Related*