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 the program running until the user wants to stop it.

Let’s start with the most important looping method…

The Ruby Each Loop

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.

Each Method With a Hash

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!

How to Use Each With Index

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}" }

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!

The 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.

Skipping Iterations With The Next Keyword

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]

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 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.

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