Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Ruby

Iterators in Ruby

5.00/5 (1 vote)
4 Mar 2016CPOL2 min read 10.8K  
Mostly used iterators in Ruby

Iterators are methods tied to a block(created using do and end) which executes statements multiple times, just like a loop. In Ruby iterators are frequently used instead of while and for loops.

Syntax:

object.iterator do
  # block tied to iterator
  statements
end

If there is only one statement inside a block then you can also write above syntax as:

object.iterator { statement }

Here block is enclosed using curly braces {}  and iterator method and block must be on the same line. So you can't do this:

object.iterator   # ERROR
{ statement }

Ruby comes with many built-in iterators, in this lesson we will focus on built-in iterators later we will learn how to create our own iterator methods.

times iterator

times  allows you to execute statements inside a block certain number of times. Here is how to use times  iterator.

Create a new file p_20_1.rb  with the following code.

#p_20_1.rb
=begin
Program to demonstrate times iterator.
This code will generate 10 random numbers
=end

10.times do
  puts rand(10)
end

Expected Output:

C:learn ruby>ruby p_20_1.rb
2
1
3
9
2
4
6
2
1
7

C:learn ruby>

If there is only one statement inside a block, then you can put statement in the same line as iterator method.

#p_20_2.rb
=begin
Program to demonstrate times iterator.
This code will generate 10 random numbers
=end

10.times { puts rand(10) }

Expected Output:

C:learn ruby>ruby p_20_2.rb
6
7
2
6
2
1
5
9
6
0

C:learn ruby>

Normally iterators return a value in each iteration, we need to write variable name within pipe character ( |  ) as the first thing inside a block. Let's access this value

#p_20_3.rb
=begin
times iterator returns a number from 0 to 1
less than total iteration made by the iterator
=end

10.times { |i| puts i }

Expected Output:

C:\learn ruby>ruby p_20_3.rb
0
1
2
3
4
5
6
7
8
9

C:\learn ruby>

upto iterator

upto iterator: It goes from x  to y , where y  must be greater than x .

#p_20_4.rb
=begin
upto iterator returns a number between x and y.
It starts with x and ends at y.
In the first iteration it returns 1.
And in the last iteration it returns 10
=end

1.upto(10) { |i| puts i }

Expected Output:

C:\learn ruby>ruby p_20_4.rb
1
2
3
4
5
6
7
8
9
10

C:\learn ruby>

downto iterator

downto iterator: It goes from x  to y , where x  must be greater than y .

#p_20_5.rb
=begin
downto iterator returns a number between x and y.
It starts with x and ends at y.
In the first iteration it returns 10.
And in the last iteration it returns 11
=end

10.downto(1) { |i| puts i }

Expected Output:

C:\learn ruby>ruby p_20_5.rb
10
9
8
7
6
5
4
3
2
1

C:\learn ruby>

step iterator

step iterator allows you to specify start position, end position and step size. It only works with array and range. step iterator when used with array accepts two arguments: the upper limit and step size. When used with range it accepts only one argument step size.

#p_20_6.rb
=begin
This program prints uses step iterator to
print only even numbers
=end

puts "step iterator with array"

10.step(20, 2) { |i| puts i }

puts "step iterator with range"

(10..20).step(2) { |i| puts i }

Expected Output:

C:\learn ruby>ruby p_20_6.rb
step iterator with array
10
12
14
16
18
20

step iterator with range
10
12
14
16
18
20

C:\learn ruby>

Iterating through collections

each iterator is the most commonly used iterator to iterate through the elements of an array, range and hashes.

Create a new file p_20_7.rb  with the following code.

#p_20_7.rb
=begin
This program uses each iterator to
access elements of an array, range and hash
=end

arr = [11,44,66,99]
puts "Iterating through array"
arr.each { |i| puts i }

###########

r = 40..50

puts "\nIterating through range"
r.each { |i| puts i }

##############

h = {
'key1'=> 'val1',
'key2'=> 'val2',
'key3'=> 'val3',
}

puts "\nIterating through hash"

# hash consist of two values key and value, so we will need two variables inside the block

h.each { |k, v| puts "#{k} : #{v}" }

Expected Output:

C:\learn ruby>ruby p_20_7.rb
11
44
66
99

C:\learn ruby>

map iterator

map iterator steps through elements of an array, range or hash and in the process creates a new array based on the values returned by the block.

Create a new file p_20_8.rb  with the following code.

#p_20_8.rb
=begin
This program uses map iterator to
create a new array from the elements of array, range and hash
=end

# map iterator with array

arr = [65,89,21,98]

new_arr = arr.map { |i| i * 2 }

puts "old array " + arr.inspect
puts "new array " + new_arr.inspect
puts
################

# map iterator with range

r = 20..30

new_r = r.map { |i| i * 3 }

puts "range " + r.inspect
puts "array created from range " + new_r.inspect
puts
################

# map iterator with hash

h = {
'key1'=> 'val1',
'key2'=> 'val2',
'key3'=> 'val3',
}

new_h = h.map { |k, v| "#{k} : #{v}" }

puts "hash " + r.inspect
puts "array created from hash " + new_h.inspect

Expected Output:

C:\learn ruby>ruby p_20_8.rb
old array [65, 89, 21, 98]
new array [130, 178, 42, 196]

range 20..30
array created from range [60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90]

hash 20..30
array created from hash ["key1 : val1", "key2 : val2", "key3 : val3"]

C:\learn ruby>

If you want to permanently alter the original array use map!  (remember that methods whose names end with exclamation point (! ) permanently alters the object to which they are applied)

each_pair iterator

We have already learnt that each iterator can be used with hashes, but Ruby provides a more efficient way to iterate through hashes using each_pair iterator.

#p_20_9.rb
=begin
This program uses each_pair iterator to
access elements of a hash
=end

h = {
  'key1'=> 'val1',
  'key2'=> 'val2',
  'key3'=> 'val3',
}

h.each_pair { |k, v| puts "#{k} : #{v}" }

Expected Output:

C:\learn ruby>ruby p_20_9.rb
key1 : val1
key2 : val2
key3 : val3

C:\learn ruby>

select iterator

select iterator returns an array of values for which code block returns true. It can be used with array, range and hash

#p_20_10.rb
=begin
This program demonstrate the use of select iterator
=end

arr = [34, 98, 56, 100, 89, 37, 11, 52]

new_arr = arr.select { |i| i % 2 == 0 }

puts new_arr.inspect

Expected Output:

C:\learn ruby>ruby p_20_10.rb
[34, 98, 56, 100, 52]

C:\learn ruby>

count iterator

count iterator is used to count elements for which code blocks returns true. It can be used with array, range and hash

#p_20_11.rb
=begin
This program demonstrate the use of count iterator
=end

arr = [34, 98, 56, 100, 89, 37, 11, 52]

n = arr.count { |i| i % 2 == 0 }

puts n

Expected Output:

C:\learn ruby>ruby p_20_11.rb
5

C:\learn ruby>

delete_if iterator

delete_if iterator deletes elements from an array for which code blocks returns true.

#p_20_12.rb
=begin
Following program demonstrate use of delete_if iterator.
=end

arr = [34, 98, 56, 100, 89, 37, 11, 52]

arr.delete_if { |i| i % 2 == 0 }

puts arr.inspect

Expected Output:

C:\learn ruby>ruby p_20_11.rb
[89, 37, 11]

C:\learn ruby>

This article was originally appeared at http://ruby.codeindepth.com/iterators-in-ruby/

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)