Choose Your Character: Ruby Iterator Edition
Programming languages have many ways to repeat instructions. While others use loops, Ruby leverages iterators to accomplish this task. Deciding what iterator to use can be tricky, but I’m here to help! First, let’s explore some basic terminology.
Loop
A Loop is a repetitive execution of a block of code; specified once and run until a specific condition is met. This action is particularly useful when you want to automate some repeatable action. An example of a loop would be:
x = 0
while x < 5
if x.even?
puts x
end
x += 1
end
# => 0
# => 2
# => 4
Iterator
An iterator is an object (or method) allowing us to iterate over a dataset (particularly arrays and hashes). To iterate over a dataset means that we can go through each object in a collection and do some repeatable action. Although similar, the defining difference between loops and iterators is that a loop needs an external object to work (e.g., x=0), whereas an iterator belongs a (or is a built in method for) a collection. An example of an iterator would be:
video_game_array = ["Call of Duty", "Mortal Kombat", "Mario Kart"]
video_game_array.each do |item|
puts item
end
# => Call of Duty
# => Mortal Kombat
# => Mario Kart
Now that we understand the basic terminology, we can now dive into the main types of iterators in Ruby.
Filter/Select
Two names for the same iterator! This iterator allows us to select specific elements from a collection based upon some condition. For example:
# I want to find all pet names that are shorter than 4 letterspets_array = ["Sidney", "Stockli", "Roo", "Peyton"]pets_array.select{|pet| pet.length < 4}# => Roo
This is particularly helpful when you want to select a specific group of elements in a collection; you’re not interested in the whole collection, just a subset of it. Find_all behaves in the same way.
Map/Collect
Again, two terms for the same iterator. Map/Collect will return a new object based upon specified calculations; or in other words, map/collect will create a new collection. For example,
numbers_array = [1, 2, 3]numbers_squared = numbers_array.map{|number| number ** 2}numbers_squared# => [1, 4, 9]numbers_array# => [1, 2, 3]
It’s important to note that the initial array did not change. We can use Map/Collect to generate a new collection based on an existing collection, but we won’t change the initial object.
Find
Find will return the first element that fulfills some specified condition (i.e., the result of this iteration will be a single element, not a collection). For example:
bike_types_array = ["Comfort", "Hybrid", "Road Bike"]bike_types_array.find{|bike| bike.include?("C")}# => Comfort
Note: Include? is a string class method in Ruby which is used to return true if the given string contains a specified string or character.
Each
Each allows us to easily perform operations on elements in a collection. This iterator is also useful for when we just want to output some data to the console. For example:
# I want a list of my favorite cities to print out in uppercasemy_favorite_cities = ["New York City", "Savannah", "Boston"]my_favorite_cities.each{|city| puts city.upcase}# => NEW YORK CITY
# => SAVANNAH
# => BOSTON
# => ["New York City", "Savannah", "Boston"]
It’s important to note that Each will not change the initial object; Each will always return the base, or original, collection.
All?/Any?
These iterators will return a boolean value after checking if a condition if met. All? will return true when all elements in a collection fulfill the condition, whereas Any? will return true if just one element in a collection fulfills the condition. For example:
numbers_array = [1, 2, 3]numbers_array.all?{|number| number.even?}# => falsenumbers_array.any?{|number| number.even?}# => true
Times
This iterator allows us to repeat tasks many times. Times is called on numbers (rather than a collection) and will return the numerical value of execution (instead of an original collection like Each). For example:
5.times do
puts "Ruby is the best language ever!"
end# => Ruby is the best language ever!
# => Ruby is the best language ever!
# => Ruby is the best language ever!
# => Ruby is the best language ever!
# => Ruby is the best language ever!
# => 5