... jusqu'au premier élément nil.

Un itérateur est un objet qui peut être utilisé pour parcourir certains ou tous les éléments d'un conteneur de bibliothèque de modèles standard. Chaque objet itérateur représente une adresse définie dans le conteneur.

En Lua, un itérateur est une structure qui prend en charge les types de pointeurs. Il peut parcourir chaque élément d'une collection.


Itérateur for générique

Le for générique stocke la fonction itératrice en interne. En fait, il stocke trois valeurs : la fonction itératrice, la constante d'état et la variable de contrôle.

L'itérateur for générique fournit les paires clé/valeur de la collection. La syntaxe est la suivante :

for k, v in pairs(t) do
    print(k, v)
end

Dans le code ci-dessus, k, v constituent la liste de variables ; pairs(t) est la liste d'expressions.

Regardez l'exemple suivant :

Exemple

array = {"Google", "Example"}

for key,value in ipairs(array)
do
   print(key, value)
end

La sortie de l'exécution du code ci-dessus est :

1  Google
2  Example

Dans l'exemple ci-dessus, nous avons utilisé la fonction itératrice ipairs fournie par défaut par Lua.

Voyons maintenant le processus d'exécution du for générique :

  • Premièrement, initialiser : évaluer l'expression après `in`. L'expression doit renvoyer les trois valeurs nécessaires au for générique : la fonction itératrice, la constante d'état et la variable de contrôle. Comme pour l'affectation multiple, si l'expression renvoie moins de trois valeurs, celles qui manquent sont automatiquement remplies avec nil, et les valeurs supplémentaires sont ignorées.
  • Deuxièmement, appeler la fonction itératrice avec la constante d'état et la variable de contrôle comme arguments (note : pour la structure for, la constante d'état est inutile ; elle est seulement obtenue lors de l'initialisation et transmise à la fonction itératrice).
  • Troisièmement, affecter les valeurs renvoyées par la fonction itératrice à la liste de variables.
  • Quatrièmement, si la première valeur renvoyée est nil, la boucle se termine ; sinon, exécutez le corps de la boucle.
  • Cinquièmement, revenez à la deuxième étape et appelez à nouveau la fonction d'itération.

En Lua, nous utilisons souvent des fonctions pour décrire des itérateurs. Chaque fois que la fonction est appelée, elle renvoie l'élément suivant de la collection. Les itérateurs Lua comprennent les deux types suivants :

  • Itérateurs sans état
  • Itérateurs à états multiples

Itérateurs sans état

Un itérateur sans état est un itérateur qui ne conserve aucun état. Par conséquent, dans les boucles, nous pouvons utiliser des itérateurs sans état pour éviter le coût supplémentaire de création de fermetures.

À chaque itération, la fonction d'itération est appelée avec les valeurs de deux variables (la constante d'état et la variable de contrôle) comme arguments. Un itérateur sans état peut obtenir l'élément suivant en utilisant uniquement ces deux valeurs.

Un exemple typique et simple d'un tel itérateur sans état est ipairs, qui parcourt chaque élément d'un tableau dont les indices doivent être numériques.

L'exemple suivant utilise une simple fonction pour implémenter un itérateur qui calcule le carré d'un nombre n :

Exemple

function square(iteratorMaxCount,currentNumber)
   if currentNumber<iteratorMaxCount
   puis
      currentNumber = currentNumber+1
   return currentNumber, currentNumber*currentNumber
   end
end

for i,n in square,3,0
do
   print(i,n)
end

La sortie de l'exemple ci-dessus est :

1    1
2    4
3    9

L'état d'itération comprend la table parcourue (la constante d'état, qui ne change pas pendant la boucle) et l'index courant (la variable de contrôle). ipairs et la fonction d'itérateur sont tous deux très simples. En Lua, nous pouvons l'implémenter comme ceci :

Exemple

function iter (a, i)
    i = i + 1
    local v = a[i]
    if v then
       return i, v
    end
end
 
function ipairs (a)
    return iter, a, 0
end

Lorsque Lua appelle ipairs(a) pour démarrer la boucle, il obtient trois valeurs : la fonction d'itérateur iter, la constante d'état a et la valeur initiale de la variable de contrôle 0. Ensuite, Lua appelle iter(a,0) et renvoie 1, a


Itérateurs à états multiples

Dans de nombreux cas, les itérateurs doivent stocker plusieurs informations d'état plutôt que simplement une constante d'état et une variable de contrôle. La méthode la plus simple consiste à utiliser des fermetures. Une autre méthode consiste à encapsuler toutes les informations d'état dans une table et à utiliser la table comme constante d'état de l'itérateur. Dans ce cas, comme toutes les informations peuvent être stockées dans la table, la fonction d'itérateur n'a généralement pas besoin d'un second paramètre.

Dans l'exemple suivant, nous avons créé notre propre itérateur :

Exemple

array = {"Google", "Example"}

function elementIterator (collection)
   local index = 0
   local count = #collection
   -- fonction de fermeture
   return function ()
      index = index + 1
      if index <= count
      puis
         -- renvoyer l'élément courant de l'itérateur
         return collection[index]
      end
   end
end

for element in elementIterator(array)
do
   print(element)
end

La sortie de l'exemple ci-dessus est :

Google
Example

Dans l'exemple ci-dessus, nous pouvons voir que elementIterator utilise une fonction de fermeture pour calculer la taille de la collection et afficher chaque élément.

Autres extensions