Iterating over collections in Ruby: Lesson 9 of My Self-Inflicted Crash Course into Ruby

Ruby provides a multitude of methods and structures for iterating or looping through arrays and collections. The most commonly used methods are the basic for and each loops. However there exists other convenience (or code bloat) methods on both arrays and integers to also perform iteration.

The basic FOR loop

The for loop in Ruby functions allows you to iterator through each item in an expression. Where the expression can be an array, collection, or a range.

for i in myArray
    puts "Value of Array index is: #{i}"
end

for j in 0..10
    puts j
end

In the second example we are using a Range. In Ruby we can define a range of numbers inclusively by use of the number . . number syntax. The above example will iterate starting at 0 and end at 10.

The Each Statement

The each iterator is similar to the for statement as it loops through the array or hash for every element setting the current element to the defined variable. The one important element to remember is that for hash objects you will need to specify two variables to hold both the key and value.

myArray.each do |var|
    puts i
end

myHash.each do |varKey, varValue|
    puts "key: #{varKey} | value: #{varValue}"
end

In addition to the main each statement Ruby has also defined additional methods to iterate over the indexes of a collection each_index and to also return both the element and its index each_with_index. However it is important to remember that the each_with_index function returns the element first then the index.

myArray.each_with_index do |value, index|
    puts "index: #{index} | value: #{value}"
end

Integer iteration with TIMES, UPTO, and DOWNTO

For those that find the for statement cumbersome Ruby has found the need to define the times, upto and downto methods for iterating.

4.times do
    puts "Hello"
end

The times method is used to execute a block of code for the specified number of times. If needed you could also get the current loop index that will start at 0 and go to times – 1.

10.times do |i|
    puts i
end

If you don’t want to iterate starting at 0 for a specific number of times but instead want to iterate over a range then you can use the upto and downto methods. These methods iterate from the integer’s value to the specified value.

1.upto(5) do |i|
    puts i 
end

15.downto(10) do |i|
    puts i
end

It is important to remember that the downto and upto method are inclusive so in the example 6 iterations of the code block will occur. Personally I don’t see the reason for these methods, all of the logic that you can perform from it can be created using a simple for loop and why would you need both an upto and downto method why not simply have a to method that could do either depending on if the specified number is larger or smaller. Seriously if you are going to add convenience methods for no other reason then to do so then atleast go all the way.

The Collect and Map functions

While we are on the topic of iteration it is important to touch on the collect and map functions. These functions are used to return a collection after performing the specified code block on each element of the existing collection. As you can tell from the name these functions are most useful in mapping a collection into a new collection with different values.

myArray = ['a','b','c','d']             #=> ["a", "b", "c", "d",]
newArray = myArray.map {|item| item.upcase}      #=> ["A", "B", "C", "D"]

Ruby definitely defines some different methods for performing collection iteration, however no new functionality is presented. Instead we see once again the existence of additional code and functions that add bloat and ambiguity to the core of Ruby. Nearing the end of my self-inflicted crash course, and to date I must say I am not impressed.

// Ruby //

Comments & Questions

Add Your Comment