🎓 A1Learner
🔍
0 of 47 lessons completed

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)
end

A 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)
end

Nil 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)
end

Key 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?