Lua - Itérateurs
Iterator est une construction qui vous permet de parcourir les éléments de la soi-disant collection ou conteneur. Dans Lua, ces collections font souvent référence à des tables, qui sont utilisées pour créer diverses structures de données comme un tableau.
Générique pour Iterator
Un générique pour itérateur fournit des paires de valeurs clés de chaque élément de la collection. Un exemple simple est donné ci-dessous.
array = {"Lua", "Tutorial"}
for key,value in ipairs(array)
do
print(key, value)
end
Lorsque nous exécutons le code ci-dessus, nous obtiendrons la sortie suivante -
1 Lua
2 Tutorial
L'exemple ci-dessus utilise la fonction d'itérateur ipairs par défaut fournie par Lua.
Dans Lua, nous utilisons des fonctions pour représenter les itérateurs. Sur la base de la maintenance de l'état dans ces fonctions d'itération, nous avons deux types principaux -
- Itérateurs apatrides
- Itérateurs avec état
Itérateurs apatrides
Par le nom lui-même, nous pouvons comprendre que ce type de fonction d'itérateur ne conserve aucun état.
Voyons maintenant un exemple de création de notre propre itérateur en utilisant une fonction simple qui imprime les carrés de n Nombres.
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
for i,n in square,3,0
do
print(i,n)
end
Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.
1 1
2 4
3 9
Le code ci-dessus peut être légèrement modifié pour imiter le fonctionnement de la fonction ipairs des itérateurs. Il est montré ci-dessous.
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
function squares(iteratorMaxCount)
return square,iteratorMaxCount,0
end
for i,n in squares(3)
do
print(i,n)
end
Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.
1 1
2 4
3 9
Itérateurs avec état
L'exemple précédent d'itération utilisant la fonction ne conserve pas l'état. Chaque fois que la fonction est appelée, elle renvoie l'élément suivant de la collection en fonction d'une deuxième variable envoyée à la fonction. Pour conserver l'état de l'élément actuel, des fermetures sont utilisées. La fermeture conserve les valeurs des variables entre les appels de fonctions. Pour créer une nouvelle fermeture, nous créons deux fonctions dont la fermeture elle-même et une usine, la fonction qui crée la fermeture.
Voyons maintenant un exemple de création de notre propre itérateur dans lequel nous utiliserons des fermetures.
array = {"Lua", "Tutorial"}
function elementIterator (collection)
local index = 0
local count = #collection
-- The closure function is returned
return function ()
index = index + 1
if index <= count
then
-- return the current element of the iterator
return collection[index]
end
end
end
for element in elementIterator(array)
do
print(element)
end
Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.
Lua
Tutorial
Dans l'exemple ci-dessus, nous pouvons voir que elementIterator a une autre méthode à l'intérieur qui utilise l'index et le nombre de variables externes locales pour renvoyer chacun des éléments de la collection en incrémentant l'index chaque fois que la fonction est appelée.
Nous pouvons créer nos propres itérateurs de fonction en utilisant la fermeture comme indiqué ci-dessus et il peut retourner plusieurs éléments pour chaque fois que nous itérons dans la collection.