SoFunction
Updated on 2025-04-09

Detailed explanation of iterators in Ruby

D Gua Ge recently wanted to build a website. In addition, he has long been thinking of learning a dynamic language. Among the programming languages ​​that meet the two conditions, Ruby and Python are the two most suitable languages. Ruby on Rails is now at its peak, and it is shining brightly! So, I chose Ruby and started learning from scratch.

I watched Ruby's iterator the day before yesterday. For someone who has only learned Java, C/C++, etc., it is definitely a shiny feeling! And it is dazzling: I didn't expect the iterator to be played like this, it's too concise, too convenient and very powerful! Then, D Gua Ge couldn't wait to write an article to introduce Ruby's iterator!

Iterator introduction

Let me briefly introduce the iterator.

1. A Ruby iterator is a simple method that can receive code blocks (for example, each method is an iterator). Features: If a method contains a yield call, then this method must be an iterator;

2. There is the following transfer relationship between the iterator method and the block: the block is passed to the iterator method as a special parameter, and the iterator method can pass parameter values ​​into the block when calling the code block using yield;

3. In fact, the function of the iterator is a callback! The class to which the iterator method belongs is only responsible for traversing the elements that need to be traversed, and the processing of elements is implemented through callback code blocks;

The container objects in it (such as arrays, Range and Hash objects, etc.) all contain two simple iterators, namely each and collect. Each can be considered the simplest iterator, which calls blocks on each element of the collection. collect, passes elements in the container to a block, and returns a new array containing the processing results after processing in the block;

Iterator details

There are many iterators in Ruby. Let’s briefly introduce Ruby’s iterators from several aspects such as strings, numbers, arrays, maps, files, directories, etc.

String iterator

In Java, there is no iterator for data of string type. So, if you need to "traverse" the string, you need to do some other processing of the string. However, it is available in Ruby. Below, we will demonstrate it through the code:

Copy the codeThe code is as follows:

str = "abc"
str.each_byte {|c| printf ">%c", c};  #

# The output is as follows: (To distinguish it from the code, D Gua Ge artificially added # in front of the output.)
# The following output is displayed, the processing method is the same.
#>a>b>c

each_byte is the iterator in the string used to process each byte. Each byte is substituted into block parameter c.

In Ruby, there are not only iterators for bytes, but also iterators for each row. Examples are as follows:

Copy the codeThe code is as follows:

str = "abc\nefg\nhijk"
str.each_line{|l| print l}

# The output is as follows:
#abc
#efg
#hijk

How about it, are you impressed by Ruby's concise but powerful iterators? ! The good show is still behind, so continue to watch it down.

Digital iterator

In Ruby, "everything is an object", and even numbers are objects. This is different from Java. Therefore, iterators for words are unheard of for me, a Java programmer. Let's write two examples to get a glimpse.

The first scenario: Perform N (such as 5) operations on a certain piece of code. In Java, you need to write a loop, but in Ruby, you only need to call the times method. The code is as follows:

Copy the codeThe code is as follows:

{print "I love https:/// \n"} # It's really that simple

# The output is as follows:
#I love https:///
#I love https:///
#I love https:///
#I love https:///
#I love https:///

The second scenario: Find the sum of numbers from 1 to 5. This is also very simple:

Copy the codeThe code is as follows:

sum = 0
(1..5).each {|i| sum += i}
print "Sum="+sum.to_s

If you use the upto function, you can also write it like this:

Copy the codeThe code is as follows:

sum = 0
(5) {|x| sum += x }
print "Sum="+sum.to_s

Sometimes, our steps may not be 1, but may be 2, such as odd sums. In this case, the step function can be used. The code is as follows:

Copy the codeThe code is as follows:

sum = 0  
(5, 2) do |y| # The second parameter of the step function is step.
   sum += y  
end 
print "Sum="+sum.to_s

It feels a bit too far. Next, we will talk about iterators related to arrays.

Array iterator

After seeing the iterators related to numbers, let’s take a look at the iterators related to arrays.

The first scenario: Convenient array and output each element. Directly upload the code:

Copy the codeThe code is as follows:

languages = ['Ruby', 'Javascript', 'Java']
languages.each_with_index do |lang, i|
    puts "#{i}, I love #{lang}!"
end

#The output is as follows:
#0, I love Ruby!
#1, I love Javascript!
#2, I love Java!

Sometimes, we need to make a selection of elements of the array, and we can do this:

Copy the codeThe code is as follows:

# Find the value that meets the criteria
b = [1,2,3].find_all{ |x| x % 2 == 1 }
# b's value is [1,3]

Sometimes, we need to delete some values ​​in the array. At this time:

Copy the codeThe code is as follows:

# Iterate and delete according to the conditions
a = [51, 101, 256]
a.delete_if {|x| x >= 100 }
The value of # a is [51]

Let’s take another example:

Copy the codeThe code is as follows:

# Find the longest word
longest = ["cat", "sheep", "bear"].inject do |memo,word|
    ( > )? memo : word
end
puts longest

#The output is as follows:
#sheep

Map iterator

In Java, if you use iterators relative to Map, you must convert the Map into a List type container. However, in Ruby, there are iterators directly targeting Map, which is very convenient:

Copy the codeThe code is as follows:

sum = 0
outcome = {"book1"=>1000, "book2"=>1000,"book3"=>4000}
{|item, price|
 sum += price
}
print "Sum="+sum.to_s

Even, we can do this:

Copy the codeThe code is as follows:

sum = 0
outcome = {"book1"=>1000, "book2"=>1000,"book3"=>4000}
{|pair|
sum += pair[1] # read value
}
print "Sum="+sum.to_s

Here is an explanation: the above program uses pair[1] to read the Map value, and if you want to read the Map key, it is written as pair[0].

If you need to output the key of the Map, you can do this:

Copy the codeThe code is as follows:

outcome = {"book1"=>1000, "book2"=>1000,"book3"=>4000}
outcome.each_key do |k|
 puts k
end

If you need to output the value of the Map, you can do this:

Copy the codeThe code is as follows:

outcome = {"book1"=>1000, "book2"=>1000,"book3"=>4000}
outcome.each_value do |v|
 puts v
end

File Iterator

I really didn't expect that Ruby also has iterators available for files. as follows:

Copy the codeThe code is as follows:

f = ("")
{|line|
 print line
}

In fact, we can use code blocks to do the same:

Copy the codeThe code is as follows:

("", "r") do |file|
    {|line|
  print line
 }
end

Using code blocks, no manual close is required. This recommendation!

Directory iterator

Many times, we need to list the file list in a certain directory and set up operations on each file, and an iterator is also needed. Ruby also considered:

Copy the codeThe code is as follows:

("c://") do |file| # Please make appropriate modifications based on your system type
 puts file
end

#If there is too much output, the result will not be posted. You can run it yourself

Ending

From the above introduction, we can see that Java and Ruby are simply weak in terms of iterators! Of course, Gua Ge D has just started learning Ruby, and there are some inappropriate or even errors in the article. Please point out that Gua Ge D will correct it as soon as possible.