Lua - Stateful Iterators
Stateful iterator as opposed to stateless iterator can hold the state of the current element using closures. Closure is a special function defined within a function which can read local variables to retain state of the function. To create a closure, we're going to create following two functions:
clousure function− internal function which can read local variables of outer function.
factory function− outer function containing state of the iterator.
Example - Custom Stateful Iterator with for loop
Let us now see an example of creating our own stateful iterator using a simple function that prints the elements of the collection.
elementIterator function is a stateful iterator and is accepting an array. First we're initializing the index as 0 as default state, then size of array is computed using # operator. As next, a closure function is created which is incrementing the index. Checking the index less than size of the array, current element is returned.
main.lua
-- Initialize an array
array = {"Lua", "Tutorial"}
-- return a stateful iterator to get values of collection passed
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
Output
When we run the above program, we will get the following output−
Lua Tutorial
Here our stateful iterator is ignoring the control variable passed by for loop and maintaining the index itself.
Example - Custom Stateful Iterator with while loop
Let us now see an example of creating our own stateful iterator using a simple function that prints the elements of the collection using while loop.
main.lua
-- Initialize an array
array = {1, 2, 3, 4, 5, 6}
-- return a stateful iterator to get values of collection passed
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
-- get the iterator on the iterator
local iterator = elementIterator(array)
-- loop through the iterator
while true
do
-- call the iterator
local element = iterator()
-- if element is nil, stop the iterator
if element == nil
then
break end
-- print the element
print(element)
end
Output
When we run the above program, we will get the following output−
1 2 3 4 5 6
Here our stateful iterator is ignoring the control variable passed by for loop and maintaining the index itself.