REDUÇÃO de Inverno
Iterator

Iterator em Ruby

O Iterador é um padrão de projeto comportamental que permite a passagem sequencial através de uma estrutura de dados complexa sem expor seus detalhes internos.

Graças ao Iterator, os clientes podem examinar elementos de diferentes coleções de maneira semelhante usando uma única interface iterador.

Complexidade:

Popularidade:

Exemplos de uso: O padrão é muito comum no código Ruby. Muitos frameworks e bibliotecas o usam para fornecer uma maneira padrão de percorrer suas coleções.

Identificação: O iterador é fácil de reconhecer pelos métodos de navegação (como next, previous e outros). O código cliente que usa iteradores pode não ter acesso direto à coleção que está sendo percorrida.

Exemplo conceitual

Este exemplo ilustra a estrutura do padrão de projeto Iterator. Ele se concentra em responder a estas perguntas:

  • De quais classes ele consiste?
  • Quais papéis essas classes desempenham?
  • De que maneira os elementos do padrão estão relacionados?

main.rb: Exemplo conceitual

class AlphabeticalOrderIterator
  # In Ruby, the Enumerable mixin provides classes with several traversal and
  # searching methods, and with the ability to sort. The class must provide a
  # method each, which yields successive members of the collection.
  include Enumerable

  # This attribute indicates the traversal direction.
  attr_accessor :reverse
  private :reverse

  # @return [Array]
  attr_accessor :collection
  private :collection

  # @param [Array] collection
  # @param [Boolean] reverse
  def initialize(collection, reverse: false)
    @collection = collection
    @reverse = reverse
  end

  def each(&block)
    return @collection.reverse.each(&block) if reverse

    @collection.each(&block)
  end
end

class WordsCollection
  # @return [Array]
  attr_accessor :collection
  private :collection

  def initialize(collection = [])
    @collection = collection
  end

  # The `iterator` method returns the iterator object itself, by default we
  # return the iterator in ascending order.
  def iterator
    AlphabeticalOrderIterator.new(@collection)
  end

  # @return [AlphabeticalOrderIterator]
  def reverse_iterator
    AlphabeticalOrderIterator.new(@collection, reverse: true)
  end

  # @param [String] item
  def add_item(item)
    @collection << item
  end
end

# The client code may or may not know about the Concrete Iterator or Collection
# classes, depending on the level of indirection you want to keep in your
# program.
collection = WordsCollection.new
collection.add_item('First')
collection.add_item('Second')
collection.add_item('Third')

puts 'Straight traversal:'
collection.iterator.each { |item| puts item }
puts "\n"

puts 'Reverse traversal:'
collection.reverse_iterator.each { |item| puts item }

output.txt: Resultados da execução

Straight traversal:
First
Second
Third

Reverse traversal:
Third
Second
First

Iterator em outras linguagens

Iterator em C# Iterator em C++ Iterator em Go Iterator em Java Iterator em PHP Iterator em Python Iterator em Rust Iterator em Swift Iterator em TypeScript