Ruby Loops: Repeating Something Many Times
In this lesson you'll learn 7 ways to write loops in Ruby. Loops are essential to any Ruby program so it's important that you study them.
What is A Loop?
A loop lets you repeat an action many times.
This allows you to:
- Go over a list of things & work with each individual element
- Repeat something a set number of times
- Keep a program running until the user wants to stop it
Let’s start with…
The most important looping method in Ruby!
The Ruby Each Loop
The Ruby method each
allows you to go over a list of items, without having to keep track of the number of iterations, or having to increase some kind of counter.
It’s the Ruby way of doing “repeat until done”.
Before you can use each
, you need a collection of items like an array, a range or a hash.
For example:
numbers = [1, 3, 5, 7]
Then you can use each like this:
numbers.each { |n| puts n }
In plain English this is saying:
“For each element in numbers
print its value.”
You tell the each method what to do with every item by using a block.
In this example, the whole thing after each
is a block:
{ |n| puts n }
What happens is that each
will use the block once for every element in the array & pass every individual element into it, so this n
is a variable that changes.
Remember:
The purpose of a loop is to iterate or visit ALL the elements from a list, this list can take many forms, but usually it’s an array.
There are different ways to do this depending on the situation.
The most common is using the each method because you don’t need to keep track of the current position within the list.
Ruby does the hard work for you & gives you the individual elements as the n
variable, but it could be any other valid variable name that you choose.
Each Method With a Hash
If you want to use each
with a hash you’ll need two parameters, one for the key
& another for the value
.
The rest of the syntax is the same & you still need a block.
Example:
hash = { bacon: 300, coconut: 200 } hash.each { |key,value| puts "#{key} price is #{value}" }
Give this a try!
How to Use Each With Index
If you want to use each
but you need the index number.
You can use the each_with_index method:
animals = ["cat", "dog", "tiger"] animals.each_with_index { |animal, idx| puts "We have a #{animal} with index #{idx}" }
This allows you to loop through an array, while having access to the current index.
Remember that the index starts at 0.
The Times Loop
This is the easiest loop you can work with.
Look at this code:
10.times { puts "hello" }
This will print the word "hello"
10 times.
There isn’t much to it & it should be easy to remember.
But what if you want the number?
In the last example, with the each
loop, we had access to this n
variable so we could print it.
You can also do that with times
.
Example:
10.times { |i| puts "hello #{i}" }
This will print hello 0
, hello 1
, hello 2
, etc.
Give it a try!
The key here is the little |i|
thing, which by the way, can be any valid variable name. It doesn’t have to be an |i|
. It could be |n|
or |foo|
, or |bacon|
…
It’s just a name!
If you are familiar with methods, this |n|
is like a method parameter.
In other words, it’s just a variable that becomes the current value for each iteration of our times
loop.
Range Looping
You may have noticed that when using the times
method it starts counting from 0.
This can be a bit inconvenient if you want to start with a different number.
You can use a range & the each
method to have more control over the starting & ending numbers.
Example:
(1..10).each { |i| puts i }
This will print all the numbers from 1 to 10.
Ruby While Loop
The while loop is available in most programming languages so it’s always useful to know. It’s also the kind of loop that you can fall-back to when everything else fails.
And there are situations when only a while
loop would make sense. For example, if you don’t know how many times you need to loop in advance.
Here’s a code example:
n = 0 while n < 10 puts n n += 1 end
This will print all the numbers from 0 to 9 (10 excluded).
Notice that there are some important components:
- The
n
variable - The condition (
n < 10
) - The
n += 1
All of these components are critical for this to work.
The variable n
holds the value we are using for counting, the condition (n < 10
) tells Ruby when to stop this loop (when the value of n
is greater or equal to 10
), and the n += 1
advances the counter to make progress.
If you forget to increase the counter in your while loop you’ll run into a program that never ends.
An infinite loop!
Ruby Until Loop
There is another keyword, until
, which is the same as while
but the condition is reversed.
If you want to loop until a bottle is full, then you can say:
“Do something WHILE the bottle is NOT full”
We have a negative statement, which we try to avoid because it makes the logic harder to understand.
With an until loop you can say this:
“Do something UNTIL the bottle IS full”
This feels a lot more natural to read & understand.
Example:
bottle = 0 until bottle == 10 bottle += 1 end
Good stuff, let’s keep going.
Skipping Iterations With The Next Keyword
You can skip the current iteration in all these loops.
How?
Other languages use the continue
statement.
In Ruby, we use next
.
Let’s say that you are going over an array of numbers & you want to skip odd
numbers.
You could do something like this:
10.times do |i| next unless i.even? puts "hello #{i}" end
The key here is the next
keyword, which skips to the next loop iteration, which is a number in this example.
A better way to do this is to use other methods like step
& select
.
Example:
(0...10).select(&:even?) # [0, 2, 4, 6, 8]
How to Stop A Loop Early
You can also break out of a loop early, before the condition is met, or before you go over all the elements of the collection.
The following example stops when it finds a number higher than 10:
numbers = [1,2,4,9,12] numbers.each do |n| break if n > 10 puts n end
The important thing here is the Ruby break statement.
When you use break
you’ll end the loop immediately, so keep that in mind.
This also works for while loops.
Bonus: The upto method
If it wasn’t clear yet, Ruby is very flexible, here’s yet another method for creating a loop.
The upto
method.
1.upto(5) { |i| puts i }
Which prints numbers from 1 to 5.
Summary
You have learned many different ways to loop in Ruby!
Including the times
method, the each
method & the while
keyword.
You have also learned how to control the loops by skipping iterations with next
& breaking out of loops with break
.
With all of these methods you NEVER have to use the for loop, which is a useless remnant from other languages.
If you want to write code that feels like Ruby (what we call “idiomatic code”) use the looping methods you learned on this guide.
Copyright RubyGuides.com