Iterators in Ruby
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/