module Iterator(T)
Overview
An Iterator allows processing sequences lazily, as opposed to Enumerable which processes
sequences eagerly and produces an Array in most of its methods.
As an example, let's compute the first three numbers in the range 1..10_000_000 that are even,
multiplied by three. One way to do this is:
(1..10_000_000).select(&.even?).map { |x| x * 3 }.first(3) # => [6, 12, 18]
The above works, but creates many intermediate arrays: one for the select call,
one for the map call and one for the take call. A more efficient way is to invoke
Range#each without a block, which gives us an Iterator so we can process the operations
lazily:
(1..10_000_000).each.select(&.even?).map { |x| x * 3 }.first(3) # => #< Iterator(T)::First...
Iterator redefines many of Enumerable's method in a lazy way, returning iterators
instead of arrays.
At the end of the call chain we get back a new iterator: we need to consume it, either
using each or Enumerable#to_a:
(1..10_000_000).each.select(&.even?).map { |x| x * 3 }.first(3).to_a # => [6, 12, 18]
Because iterators only go forward, when using methods that consume it entirely or partially –
to_a, any?, count, none?, one? and size – subsequent calls will give a different
result as there will be less elements to consume.
iter = (0...100).each
iter.size # => 100
iter.size # => 0
To implement an Iterator you need to define a next method that must return the next
element in the sequence or Iterator::Stop::INSTANCE, which signals the end of the sequence
(you can invoke stop inside an iterator as a shortcut).
For example, this is an iterator that returns a sequence of N zeros:
class Zeros
  include Iterator(Int32)
  def initialize(@size : Int32)
    @produced = 0
  end
  def next
    if @produced < @size
      @produced += 1
      0
    else
      stop
    end
  end
end
zeros = Zeros.new(5)
zeros.to_a # => [0, 0, 0, 0, 0]
The standard library provides iterators for many classes, like Array, Hash, Range, String and IO.
Usually to get an iterator you invoke a method that would usually yield elements to a block,
but without passing a block: Array#each, Array#each_index, Hash#each, String#each_char,
IO#each_line, etc.
Included Modules
Defined in:
collection/unique.crInstance Method Summary
Instance methods inherited from module Enumerable(T)
  
  
    
      accumulate(init : U) : Array(U) forall Uaccumulate : Array(T)
accumulate(init : U, &block : U, T -> U) : Array(U) forall U
accumulate(&block : T, T -> T) : Array(T) accumulate, mex : T mex, mex_sorted : T mex_sorted, tally(*, default : Int32) : Hash(T, Int32) tally, unique : self
unique(&) : self unique