What is the difference between the enumerators returned by the enumerable methods when no block is given?

ary = [1, 2, nil, 4]
enu1 = ary.find
enu2 = ary.filter
enu3 = ary.map
[enu1.next, enu1.next, enu1.next, enu1.next]
[enu2.next, enu2.next, enu2.next, enu2.next]
[enu3.next, enu3.next, enu3.next, enu3.next]

The previous 3 arrays are the same.

So, what is there a reason for choosing one method over the other?

If you don’t give a block, they each return an enumerator - see the documentation module Enumerable - Documentation for Ruby 3.0.0

The enumerator can be used to do the original task of the method by using each, so each of your enu values is different.

2.7.2 :019 > ary
 => [1, 2, nil, 4] 
2.7.2 :020 > ary.filter {|i| i && i%2 == 0}
 => [2, 4] 
2.7.2 :021 > enu2 = ary.filter
 => #<Enumerator: [1, 2, nil, 4]:filter> 
2.7.2 :022 > enu2.each {|i| i && i%2 == 0}
 => [2, 4] 
2.7.2 :023 > enu3 = ary.map
 => #<Enumerator: [1, 2, nil, 4]:map> 
2.7.2 :024 > enu3.each {|i| i && i%2 == 0}
 => [false, true, nil, true] 

Notice how using enu2 applies filter, but using enu3 applies map. This in spite of each being called using each and the same block.

2 Likes

Thank you.

This is the first time I see this way of using the enumerators. The documentation mentions that with no block, an enumerator is returned, but there is not a single example of how to use those enumerators.

Thank you very much!

So, to activate the task of “filter”, “find”, “map”, or whatever method was used to create the enumerator, we have to use each with block. Is that the only interface? I suppose we could use each_with_index, or with_object (which is a reduce). What happens with reduce then?

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs