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.
A loop lets you repeat an action many times.
This allows you to:
Let’s start with the most important looping method…
Before you can use the each loop 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 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.
If you want to use each
with a hash you will need two parameters (one for the key
& another for the value
).
Example:
hash = {bacon: 300, coconut: 200} hash.each { |key,value| puts "#{key} price is #{value}" }
Give this a try!
There are cases where 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 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.
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.
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:
n
variablen < 10
)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!
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.
In all of these loop types you can skip iterations.
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]
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 key here is the Ruby break
keyword.
When you use break
you’ll end the loop immediately, so keep that in mind.
This also works for while loops.
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