Project

General

Profile

Feature #708

Updated by sawa (Tsuyoshi Sawada) about 4 years ago

=begin 
  There are a number of methods in `Enumerable` that Enumerable which build an `Array` Array of results from the entire collection: `map`, `select`, `take`, collection - e.g. map, select, take etc. 

 
 
  I propose that the `Enumerator` Enumerator class have its own implementations of these methods, which return another `Enumerator`. Enumerator. Enumerators can then be chained: 

 ```ruby 
 
 
    seq.to_enum.map { ... }.select { ... }.take(...).each { |x| puts x } 
 ``` 

 
 
  This runs horizontally, "horizontally": that is, each element is processed left to right. No intermediate arrays are created, and it works happily with sequences of arbitrary length. 

 infinite sequences. 
 
  There are precendents for `SomeClass#select` SomeClass#select behaving differently to `Enumerable#select`. Enumerable#select. For example, `Hash#select` Hash#select now returns a `Hash`. Hash. So I believe it would be reasonable for `Enumerator` Enumerator to return another `Enumerator`. 

 Enumerator. 
 
  You can then choose between array-building or lazy evaluation, depending on whether there is an Enumerator in the chain. Of course, the last Enumerator has to be turned into something useful, e.g. by calling `to_a` to_a or `each each { ... }`. 

 }. 
 
     # Normal 

 ```ruby 
 
     res = (1..1_000_000).map { |x| x * 2 }.take(100) 
 ``` 

 
     # Lazy 

 ```ruby 
 
     res = (1..1_000_000).to_enum.map { |x| x * 2 }.take(100).to_a 
 ``` 

 
 
  I have attached a simple implementation of this for `select`, `map`, `take` select, map, take and a new method `skip`. skip. There are further methods like `take_while`, `zip` take_while, zip and so on which would also need to be implemented. 
 =end 

Back