In programming, we often need to go through a list of values one at a time. For example, we may want to print each item in a collection (array, hash, etc.) or add numbers in a range.
Ruby provides two primary ways to do this:
- The
forloop - The
eachloop
Both loops are used to go through (iterate over) each item in a collection or a range.
Let's explore each of them and see how they're related, starting with the for loop.
Ruby for Loop
The for loop is used to iterate over a range or a collection (like arrays or hashes), one at a time. Its syntax is:
for variable in collection
# Code to execute
end
Here,
collection- A range of values, or a collection of values like arrays or hashes.variable- A placeholder that takes the value of each element in thecollectionduring each iteration.
Here's how it works:
- The
forloop iterates over the elements of thecollection. - In every iteration, the
variabletakes the value of the currentcollectionelement. It is then reassigned to the next element in the following iteration. - The loop ends once all the elements have been iterated over.
Note: Many Ruby programmers prefer the each loop over the for loop when iterating over collections.
Example 1: Ruby for Loop with Range
for num in 4..6
puts num
end
Output
4 5 6
Here, the for loop iterates over the range 4..6. As a result, the loop runs three times over the numbers 4, 5, and 6.
In each iteration of the loop, the variable num takes values from 4 to 6, which is then printed to the screen. Here's how it works:
| Loop Iteration | Value of num |
|---|---|
| First | 4 |
| Second | 5 |
| Third | 6 |
Example 2: Ruby for Loop with Array
people = ["Bob", "Alex", "Sharon", "Cassie"]
for person in people
puts person
end
Output
Bob Alex Sharon Cassie
Here, the for loop iterates over the people array. In each iteration of the loop, the variable person takes the corresponding element of the array. Here's how this works:
| Loop Iteration | Value of person |
|---|---|
| 1 | "Bob" |
| 2 | "Alex" |
| 3 | "Sharon" |
| 4 | "Cassie" |
Example 3: Ruby for Loop with Hash
# Create a hash named 'person'
# "name", "age", and "city" are keys
# "Alice", 30, and "Paris" are the corresponding values
person = { "name" => "Alice", "age" => 30, "city" => "Paris" }
for key, value in person
puts "#{key}: #{value}"
end
Output
name: Alice age: 30 city: Paris
In this example, we created a hash named person. Then, we used a for loop to iterate over the hash.
In each iteration of the loop, the key and value variables of the loop take a key-value pair from the hash. Here's how it works:
| Loop Iteration | key | value |
|---|---|---|
| 1 | "name" |
"Alice" |
| 2 | "age" |
30 |
| 3 | "city" |
"Paris" |
Ruby each Loop
The each loop is another way to iterate over collections. It is preferred by Ruby developers over the for loop due to its readability. Its syntax is:
collection.each do |item|
# Code using item
end
Here,
collection- A collection of values like arrays or hashes.item- A placeholder that takes the value of each element in thecollectionduring each iteration.
Example 4: Ruby each Loop with Range
(4..6).each do |num|
puts num
end
Output
4 5 6
Here, the each loop iterates over the range 4..6. As a result, the loop runs three times over the numbers 4, 5, and 6.
In each iteration of the loop, the variable num takes values from 4 to 6, which is then printed to the screen. Here's how it works:
| Loop Iteration | Value of num |
|---|---|
| First | 4 |
| Second | 5 |
| Third | 6 |
Example 5: Ruby each Loop with Array
people = ["Bob", "Alex", "Sharon", "Cassie"]
people.each do |person|
puts person
end
Output
Bob Alex Sharon Cassie
Here, the each loop runs once for each item in the people array.
In each iteration, the person variable takes a single element from the people array, which is similar to how our for loop example works:
| Loop Iteration | Value of person |
|---|---|
| 1 | "Bob" |
| 2 | "Alex" |
| 3 | "Sharon" |
| 4 | "Cassie" |
Example 6: Ruby each Loop with Hash
# Create a hash named 'person'
# "name", "age", and "city" are keys
# "Alice", 30, and "Paris" are the corresponding values
person = { "name" => "Alice", "age" => 30, "city" => "Paris" }
person.each do |key, value|
puts "#{key}: #{value}"
end
Output
name: Alice age: 30 city: Paris
Here, the each loop runs once for each item in the person hash.
In each iteration, the key and value variables of the loop take a key-value pair from the hash. Here's how it works:
| Loop Iteration | key | value |
|---|---|---|
| 1 | "name" |
"Alice" |
| 2 | "age" |
30 |
| 3 | "city" |
"Paris" |
Frequently Asked Questions
In Ruby, the one-line syntax for the each loop uses curly braces {} instead of do...end:
collection.each { |item| # code using item }
Example
# With range
(1..3).each { |i| puts i }
# With array
[4, 5, 6].each { |i| puts i }
my_hash = { "name" => "Revan", "age" => 40 }
# With hash
my_hash.each { |key, value| puts "#{key}: #{value}" }
Output
1 2 3 4 5 6 name: Revan age: 40
In Ruby, the for loop is internally built on top of the each method. So when you write a for loop, Ruby is actually calling each behind the scenes.
As a result, these two loops are almost identical. However, the two loops differ when it comes to variable scope:
- The
forloop variable belongs to the same scope as the one in which the loop is written. In other words, you can use the variable outside the loop. - The
eachloop variable only belongs inside the loop, and cannot be used outside it.
As mentioned in the previous FAQ, you can use for loop variables outside the loop, but you can't do the same with the each loop.
Example: Scope of the for Loop
for i in 1..3
puts "i = #{i}"
end
# Valid: Using i outside the for loop
puts "i = #{i}"
Output
i = 1 i = 2 i = 3 i = 3
Here, we can access the i variable outside the for loop because the scope of the for loop is the same as the one in which the loop is written.
Example: Scope of the each Loop
(1..3).each do |i|
puts "i = #{i}"
end
# Invalid: Using i outside the each loop
puts "i = #{i}"
Output
i = 1 i = 2 i = 3 main.rb:6:in '<main>': undefined local variable or method 'i' for main (NameError)
As you can see, we get a NameError when trying to access the i variable outside the each loop.
That's because the i variable is local to the block given to the each method. It is not accessible outside the block.
In other words, the each loop has its own scope (unlike the for loop).