Now that we've talked about arrays, let's talk about looping.
numbers = [1,2,3,4,5]
Here we have a numbers array. We can iterate through each item in the array with the each method. Programmers will use the word iterate a lot - it means to go through each item one by one. Let's look at an example:
numbers.each do |i|
puts i
end
1
2
3
4
5
=> [1, 2, 3, 4, 5]
As you can see, the program is going through each number in the numbers array, and printing it out. There's a few new things we have never seen before. First, let's look at the do and end.
The code that is inbetween do and end is called a block. A block is a piece of code that can be executed. In our example, our block consists of puts i.
Blocks
Blocks in Ruby are a set of instructions that are passed around your program.
Blocks are created either with
doandend, or with{}s. For example, these two pieces of code do the same thing:numbers.each do |i| puts i endnumbers.each {|i| puts i}At first, converting these two syntaxes can be confusing. An easy way to remember the syntax is to replace
dowith{andendwith}and vice-versa.The
iinbetween the|s is a block argument. Block arguments are basically variables that can be used within the block. The arguments can be named anything. The|characters are called pipe characters, and the variable inbetween them are the block arguments.
|i| is called a block argument. The block argument acts exactly like a regular variable, except it is only valid within the block.
numbers.each do |i|
# i works inside this block
# Again, the block starts at 'do' and ends at 'end'
puts i
end
# i doesn't work outside of the block
puts i
=> NameError: undefined local variable or method `i' for main:Object
Also, the block argument (the variable between the pipe characters) can be named anything:
numbers.each do |random_name|
puts random_name
end
Even though we changed i to random_name, the result is still the same:
1
2
3
4
5
=> [1, 2, 3, 4, 5]
However, it is good practice to name variables in a way that it makes sense. In other words, instead of random_name, naming the variable something like i or n or number is more appropriate.
One of my teachers from college once said that naming variables is one of the hardest things about programming. I'm not sure if I completely agree, but it is true that naming variables is extremely important. To write good expressive code, it is important to name variables in a way that makes sense.
Let's take a look at this code once again:
numbers.each do |i|
puts i
end
Here is how you should read the above code in English: For each item (i) in the numbers array, print out the item (i).
Inside the block, we can run any piece of code. Take a look at the following piece of code:
numbers.each do |i|
puts i * 2
end
Result:
2
4
6
8
10
=> [1, 2, 3, 4, 5]
As you can see, the program printed out each number multiplied by 2.
Let's take a look at another example. First, let's declare an array and push in some strings:
countries = []
countries.push("Nepal")
countries.push("Japan")
countries.push("Malaysia")
To give you a refresher, the
pusharray method pushes the element passed in as the parameter to the array.
Now let's iterate through each country:
countries.each do |country|
puts "#{country} is awesome!"
end
Nepal is awesome!
Japan is awesome!
Malaysia is awesome!
Let's go over each step of this program.
countries array with the each methodcountry. This way we can reference country inside the blockcountry is equal to "Nepal"
country is equal to "America"
country is equal to "Malaysia"
Most languages have a while loop. While loops are pretty straightforward:
i = 0
while (i < 5) do
puts i
i += 1
end
Result:
0
1
2
3
4
While loops execute the code inbetween do and end until the condition (in this case i < 5) is false.
while (condition_is_true) do
# execute code here
end
Ruby has another way to loop, which is the times loop.
10.times do |i|
puts i
end
Result:
0
1
2
3
4
5
6
7
8
9
=> 10
As you can see, the placeholder variable i starts at 0 and increments each time it loops.
Another example:
5.times do
puts "this is spam"
end
Result:
this is spam
this is spam
this is spam
this is spam
this is spam
=> 5
Again, the code inbetween do and end is executed.
You can also loop using upto.
1.upto(10) do |n|
puts n
end
Result:
1
2
3
4
5
6
7
8
9
10
Similarly, there is a downto loop as well.
10.downto(0) do |n|
puts n
end
Result:
10
9
8
7
6
5
4
3
2
1
0
Write a program the does the following:
The results should be case insensitive
"Pizza" and "pizza" should be counted as the same wordThe program should run like this:

This is a tricky problem! Good luck on this challenge!