Range Over Iterators in Lua On this page Iterating over Custom Data Structures and Infinite Sequences in Lua# Starting with version 1.23, Lua has table functions that allow us to iterate over any table using pairs and ipairs. Let’s explore how to implement iterators in Lua for a custom data structure and infinite sequences.
Consider a List
type, which is a linked list in Lua. We will add elements to the list and iterate over them using an iterator function.
List = {}
List.__index = List
function List : new ()
local self = setmetatable ({}, List )
self.head = nil
self.tail = nil
return self
end
Node = {}
Node.__index = Node
function Node : new ( value , next )
local self = setmetatable ({}, Node )
self.value = value
self.next = next
return self
end
function List : push ( value )
local newNode = Node : new ( value , nil )
if not self.tail then
self.head = newNode
self.tail = newNode
else
self.tail . next = newNode
self.tail = newNode
end
end
function List : all ()
local function iterator ( list , node )
if node == nil then
return list head
else
return node.next
end
end
return iterator , self , nil
end
-- Create a new list and push values to it
local lst = List : new ()
lst : push ( 10 )
lst : push ( 13 )
lst : push ( 23 )
-- Iterate over all elements in the list using the custom iterator
for node in lst : all () do
print ( node.value )
end
-- Collecting all values into a table
local all = {}
for node in lst : all () do
table.insert ( all , node.value )
end
print ( "all: " , table.concat ( all , ", " ))
-- Infinite Fibonacci Sequence
function genFib ()
local a , b = 1 , 1
-- The infinite iterator function
return function ()
local value = a
a , b = b , a + b
return value
end
end
-- Iterate over Fibonacci numbers until breaking condition
for n in genFib () do
if n >= 10 then break end
print ( n )
end
Explanation# Let’s break down the Lua code:
List and Node Definitions :
We define a List
table structure that can hold our linked list. Each List
has a head
and a tail
. The Node
table structure holds individual elements, each containing a value
and a next
pointer. Push Method :
The push
method adds a new node to the list. If the list is empty, it initializes the head
and tail
. Otherwise, it appends to the tail. Iterator for All Elements :
The all
method returns an iterator function. This function is used to iterate over all elements in the list. The iterator
function returns the next node each time it is called, starting from the head. Usage :
We create a list, add some elements using the push
method, and then iterate over them using for node in lst:all() do
. We also collect all elements into a Lua table using table.insert
and print them using table.concat
. Infinite Fibonacci :
The genFib
function returns an infinite iterator for Fibonacci numbers. The iteration proceeds indefinitely until a break condition is met (if n >= 10 then break
). This approach to iterators in Lua allows for clean and idiomatic iteration over both finite and potentially infinite sequences.