DEV Community

Andrew Lewell
Andrew Lewell

Posted on

A Beginner's Guide to Ruby Enumerables

Ruby's Enumerable module is a collection of built-in methods that are used to iterate over collections of data. These powerful methods allow the user to manipulate arrays and hashes. Below is a brief look at some of the more commonly used Enumerables I have come across during my journey learning to code.

What are arrays and hashes?

Before we dive into the Enumerables themselves, let's quickly recap on arrays and hashes.

An array is a data structure consisting of a collection of elements, each identified by an index. Due to this index, an array can be considered an ordered list. In Ruby, arrays are denoted with square brackets. Indexes start at 0, so the first element would be index 0, second would be index 1, third would be index 2, etc.

colours = ["red", "green", "blue"]

A hash is a data structure consisting of a collection of keys and their corresponding value. Together, they are called a key value pair. They are similar to arrays, but have a key instead of a hidden integer index.

british_weather = {temperature: "cold", rainfall: "lots"}

It is possible to nest both arrays inside hashes, and hashes inside arrays. This allows Ruby developers to map out almost any data set imaginable.

.each

The .each method is used to iterate over elements in an array, or key value pairs in a hash.

colours = ["red", "green", "blue"]
colours.each do |colour|
  puts "This is #{colour}!"
end 

#=> "This is red!"
#=> "This is green!"
#=> "This is blue!"

The .each method (and many of the other Enumerable methods) takes in two arguments: an element and a block. The element is inside the pipes, and is used to indicate the individual element being used within the block in the current iteration.

The block is everything within the do and end and this code is run on each element in the array. In this case, puts "This is #{colour}!" is being run on each element of the colours array.

Note: it is possible to replace do and end with { and } to keep the code on one line. Using the .each method with a hash is the same syntax, except both the key and value are part of the element argument.

colours.each do { |colour| puts "This is #{colour}" }


hash.each do { |key, value| block }

The .each method is non-destructive, meaning it will leave the original array/hash unchanged. But what if we need to modify the original array or hash?

.map

The .map method behaves in a similar way to .each, except that the original array is mutated based on the code within the block.

colours = ["red", "green", "blue"]
colours.map { |colour| colour.capitalize }

#=> ["Red", "Green", "Blue"]

In this example, the capitalize method is being used on each element of the array, mutating the original colours array.

.reduce

The .reduce method will combine all elements of an array or hash into a single value, based on a given block or a symbol operator.

costs = [5, 5, 10, 2, 1]
costs.reduce(:+)

#=> 23

The :+ symbol operator here will add each element together, resulting in a total value. There are many different uses for .reduce depending on the operator or code block passed in.

.select

The .select method returns a new array with all elements from an array that return true for a given block.

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
nums.select { |num| num > 5 }

#=> [6, 7, 8, 9, 10]

The .select method iterates over all numbers in the nums array, and checks if the number is greater than 5. All elements that satisfy this logic are placed into a new array.

The .find method behaves in a similar way, but returns the first element that satisfies the block, instead of an array of all elements that do.

.max_by/.min_by

These methods will select from an array or hash the maximum or minimum element based on a given block.

animals = ["tiger", "gorilla", "rat"]

animals.max_by { |animal| animal.length }
#=> "gorilla" 

animals.min_by { |animal| animal.length }
#=> "rat" 

animals.max_by(2) { |animal| animal.length }
#=> ["gorilla", "tiger"]

As you can see, the .max_by method selects the longest string because of the .length in the block, and .min_by selects the shortest string. There is also an optional argument to be passed in so you can select the max n or min n.

There are over 57 different Enumerables so I will not cover each of them here but please refer to the Ruby Enumerables documentation below in sources to dive deeper into these fantastic built in methods. Hopefully this post will have helped introduce you to the power of Ruby Enumerables.

Sources

https://ruby-doc.org/core-2.6.5/Enumerable.html
https://en.wikipedia.org/wiki/Array_data_structure
https://docs.ruby-lang.org/en/2.0.0/Hash.html

Top comments (0)