SOLDES de printemps
Itérateur

Itérateur en Ruby

L’Itérateur est un patron de conception comportemental qui permet de parcourir une structure de données complexe de façon séquentielle sans exposer ses détails internes.

Grâce à l’itérateur, les clients peuvent parcourir les éléments de différentes collections de la même manière en utilisant une seule interface.

Complexité :

Popularité :

Exemples d’utilisation : L’itérateur est très répandu en Ruby. Il est utilisé dans de nombreux frameworks et bibliothèques pour fournir une méthode de parcours standard de leurs collections.

Identification : L’itérateur peut facilement être reconnu grâce aux méthodes de parcours (comme next, previous et d’autres). Le code client qui utilise les itérateurs n’a pas forcément d’accès direct aux collections parcourues.

Exemple conceptuel

Dans cet exemple, nous allons voir la structure de l’Itérateur. Nous allons répondre aux questions suivantes :

  • Que contiennent les classes ?
  • Quels rôles jouent-elles ?
  • Comment les éléments du patron sont-ils reliés ?

main.rb: Exemple conceptuel

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: Résultat de l’exécution

Straight traversal:
First
Second
Third

Reverse traversal:
Third
Second
First

Itérateur dans les autres langues

Itérateur en C# Itérateur en C++ Itérateur en Go Itérateur en Java Itérateur en PHP Itérateur en Python Itérateur en Rust Itérateur en Swift Itérateur en TypeScript