Lua Iterators
An iterator is a function that hands out one value at a time from a set of values. Each call gives the next value, and nil means the values are finished.
A countdown iterator in a generic for
The countdown factory builds an iterator that remembers n as an upvalue. The loop prints each handed-out value until nil ends it.
local function countdown()
local n = 3
return function()
if n == 0 then return nil end
local v = n
n = n - 1
return v
end
end
for v in countdown() do
print(v)
endA squares iterator with a limit
This factory takes a limit of 4. Its iterator hands out one square per call.
local function squares(limit)
local i = 0
return function()
i = i + 1
if i > limit then return nil end
return i * i
end
end
for s in squares(4) do
print(s)
endNil marks the end
This iterator hands out one word and then finishes. Calling it by hand shows the nil that ends a loop.
local function once()
local done = false
return function()
if done then return nil end
done = true
return "only"
end
end
local it = once()
print(it())
print(it())Example
local function walk(t)
local i = 0
return function()
i = i + 1
if t[i] == nil then return nil end
return i, t[i]
end
end
local fruits = {"apple", "banana", "cherry"}
for i, v in walk(fruits) do
print(i, v)
endKey points
- Iterator: a function that hands out the next value each time it is called.
- End signal: an iterator returns nil when its values run out.
- Generic for: a for loop can run on any iterator function.
- Factory: a factory function builds and returns a new iterator.
- Upvalues: the values a returned function remembers from the place where it was made are called upvalues.
- Fresh start: each factory call makes an iterator that starts again from the beginning.
In this example, the walk factory builds an iterator that steps through an array table one position at a time. Each call returns the next position and its value, and the call past the last item returns nil. The generic for prints the same positions and values that ipairs would give for this table.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does an iterator return when its values have run out?