Les langages / Lua / Coroutines et iterateurs
Itérateurs personnalisés
Les itérateurs permettent de parcourir des données personnalisées avec des boucles for. Lua permet de créer des itérateurs stateless (sans état) ou stateful (avec état) pour tout type de collection.
Itérateur simple
-- Itérateur qui compte de 1 à n
function compter(n)
local i = 0
return function()
i = i + 1
if i <= n then
return i
end
end
end
-- Utilisation
for nombre in compter(5) do
print(nombre) -- 1, 2, 3, 4, 5
end
-- Itérateur avec pas personnalisé
function compteurPas(debut, fin, pas)
local i = debut - pas
return function()
i = i + pas
if i <= fin then
return i
end
end
end
for n in compteurPas(0, 10, 2) do
print(n) -- 0, 2, 4, 6, 8, 10
end
Itérateur stateless
-- Itérateur pour parcourir à l'envers
function rpairs(t)
-- Fonction itératrice
local function iter(t, i)
i = i - 1
if i >= 1 then
return i, t[i]
end
end
-- Retourne: fonction, table, état initial
return iter, t, #t + 1
end
-- Utilisation
local fruits = {"Pomme", "Banane", "Orange"}
for i, fruit in rpairs(fruits) do
print(i, fruit)
end
-- 3 Orange
-- 2 Banane
-- 1 Pomme
Itérateur pour filtrer
-- Itérateur qui filtre les valeurs
function filtrer(t, predicat)
local i = 0
return function()
i = i + 1
while i <= #t do
local valeur = t[i]
if predicat(valeur) then
return i, valeur
end
i = i + 1
end
end
end
-- Filtrer les nombres pairs
local nombres = {1, 2, 3, 4, 5, 6, 7, 8}
for i, n in filtrer(nombres, function(x) return x % 2 == 0 end) do
print(i, n) -- 2 2, 4 4, 6 6, 8 8
end
Itérateur chaînable
-- Créer un itérateur chaînable
local Iter = {}
function Iter.new(t)
return setmetatable({data = t}, {__index = Iter})
end
function Iter:map(fn)
local result = {}
for i, v in ipairs(self.data) do
table.insert(result, fn(v))
end
return Iter.new(result)
end
function Iter:filter(fn)
local result = {}
for i, v in ipairs(self.data) do
if fn(v) then
table.insert(result, v)
end
end
return Iter.new(result)
end
function Iter:toArray()
return self.data
end
-- Utilisation chaînée
local nombres = {1, 2, 3, 4, 5}
local resultat = Iter.new(nombres)
:filter(function(x) return x % 2 == 0 end)
:map(function(x) return x * 2 end)
:toArray()
for _, v in ipairs(resultat) do
print(v) -- 4, 8
end
1 exercice pour cette lecon
Les exercices demandent un compte : il faut bien enregistrer votre progression quelque part. La lecture, elle, reste libre. Creer un compte
- Itérateur personnalisé difficile 35 XP