Ruby: A brief guide to enumerables

Bill Feng
4 min readJun 22, 2021

In Ruby, Arrays are the easiest data structure used to store information. Students in a class can be listed in an array, your pets can be put in an array, heck even arrays can be stored in an array. Not to mention, the Array class has many methods to combine, reverse, or even shuffle its arrays. However, what if we want to search for something in the array or apply some function to each element in the array? This is where Ruby Enumerables come in.

Ruby Enumerables

Ruby Enumerables are methods that allow you to enumerate, or traverse, through your array. Suppose you wanted to go through your array of Students, and retrieve the name of each of your students. The naive approach would be to use a simple while loop.

The naive approach

The #each Enumerable

This does the job, but what if we had to do this with different types of data? It would be better if we could have a way to reduce the amount of excess code. This is where the #each method can come into play. The #each enumerable is the simplest, and traverses through the provided data. So, we can use it to simplify our code:

The .each enumerable

Note that we used braces { } and pipes | |. Braces are used to specify a code block, while the pipes are used to specify inputs to the code block. In each iteration, a new element of the students array is being passed into the code block as the variable student. With this basic enumerable, we already can implement our own actions on the elements of the array. Even the #each enumerable has similar modified functions, such as #each_with_object which allows an array to be passed in to be used to store things, or #each_with_index for those that are used to having the index from for loops in languages like C or Java.

The #map Enumerable

While #each provides us with customizability, for our purposes, a more specific enumerable would reduce our work, namely #map.

The .map enumerable in action

The #map enumerable creates a new array for us, and we have to do way less typing and managing the new array. Besides being able to easily apply functions to arrays, enumerables also provide an easy way to search for things in an array.

Some Search Enumerables

The #find Enumerable

The same as the #detect enumerable, these functions do exactly what they sound like. They iterate through the data, and run a test specified in the code block, and either return the first object that lead to true returning from the code block, or return nil if none resulted. This is useful in two cases:

  1. We want to check whether there’s something that satisfies our condition.
  2. We want to get the first object that satisfies our condition.

Consider if we had an array to store the groups of people waiting in line at an amusement park. The group objects have the number of people in the group. Theres two seats available, so we can take a party of two from the line. If everything was digitalized, we could simply just use the #find method to find the first party of two in the line. Admittedly, this example is a bit off, since realistically, we could just look through the first few groups, but you get the point!

The #select Enumerable

Also known as #find_all, these methods allow for selecting elements that satisfy a certain criteria test specified in the code block. Consider the following example where this may be useful. Suppose we have a list of pizza orders stored in an array, and because we have an excess of mushrooms at our shop, we want to prioritize orders with mushrooms. We can use #select, specifying a code block that checks whether mushrooms are in the toppings of the order. Below is a possible implementation:

Juicy one-liner for finding the mushroom orders

Quite a simple one-liner to complete a potentially annoying implementation by writing a standard loop. Note here we also used .find nested in our code block.

Enumerables to Generate Statistics

There are also Ruby enumerables to help with condensing data.

The #inject Enumerable

Also known as #reduce, this enumerable has many built-in options for applying a binary option two the elements of the data. The simplest way is just by specifying an operator, but there also is the option to have a specific starting value. The following lines of code all compute the factorial of 10 using this enumerable:

Different ways for calculating factorial with .inject

We can also easily find the sum of the data, and since we have a code block to work with, we can customize and do something like find the shortest String in the array.

The #max/#min Enumerable

We can easily find the max or min of a set of data with these enumerables. Interestingly, if the elements are things like objects or we want to find the max length of a string, we need to supply our own comparison function in the code block. For example, this is how we would find the shortest string:

Finding the shortest string

Specifying an argument n to #min also allows for us to get the smallest n elements. Specifying a comparison function is a bit annoying in this case… luckily that’s what the #min_by and #max_by functions were designed for. These functions assume that the output from the code block is orderable, and since we are finding the length, they are, and we can simplify our code:

Finding the shortest string, but better

In conclusion, Ruby enumerables provide the ease of use of the language and can make prototyping/programming in Ruby faster. More time can be spent on thinking rather than mindlessly typing while loops. For a full reference on enumerable methods, reference the official docs here.

--

--