Lua iterator
An iterator is an object that can be used to traverse some or all of the elements in a standard template library container, each iterator object representing a determined address in the container.
In Lua
the iterator is a structure that supports pointer types and can traverse every element of the collection.
Generic for iterator
Generics for
save the iterative function internally, which actually holds three values: the iterative function, the state constant, and the control variable.
Generics for
the iterator provides the collection’s key/value
,the syntax format is as follows:
for k, v in pairs(t) do
print(k, v)
end
In the above code, k and v are the list of variables pairs(t)
is a listof expressions.
View the following examples:
Example
array = {"Google", "Runoob"}
for key,value in ipairs(array)
do
print(key, value)
end
The output of the above code execution is as follows:
1 Google
2 Runoob
In the above example, we used the Lua
iterative function provided by default ipairs
.
Let’s take a look at generics execution process of for
:
First, initialize, calculate
in
the value of the later expression, which should return a generic typefor
three values are required: iterative function, state constant, and control variable; as with multi-valued assignment, if the number of results returned by the expression is less than three, it will be automatically usednil
make up, the extra part will be ignored.Second, call the iterative function with state constants and control variables as parameters (note: for
for
structurally, the state constantis useless, just gets its value at initialization and passes it to the iterative function).Third, assign the value returned by the iterative function to the list of variables.
Fourth, if the first value returned is the end of the nil loop, otherwise the loop body is executed.
Fifth, go back to the second step and call the iterative function again
In Lua, we often use functions to describe iterators, and each time we call this function, we return the next element of the collection. Lua
there are two types of iterators for:
Stateless iterator
Multi-state iterator
Stateless iterator
Stateless iterators are iterators that do not retain any state, so we can use stateless iterators in the loop to avoid the extra cost of creating closures.
At each iteration, the iterative function is called with the values of two variables (state constant and control variable) as parameters, and a stateless iterator uses only these two values to get the next element.
A typical simple example of this stateless iterator is ipairs, which iterates through every element of an array whose index needs to be a numericvalue.
For the following example, we use a simple function to implement the iterator to square the number n:
Example
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
for i,n in square,3,0
do
print(i,n)
end
The output result of the above example is:
1 1
2 4
3 9
The state of the iteration includes the table that is traversed (the state constant that does not change during the loop) and the current index subscript (control variable) ipairs
and iterative functions are simple,and we can do this in Lua:
Example
function iter (a, i)
i = i + 1
local v = a[i]
if v then
return i, v
end
end
function ipairs (a)
return iter, a, 0
end
When Lua calls ipairs(a)
when he starts the loop, he gets three values:the iterative function iter
, the state constant a, the initial value of the control variable 0; then Lua calls iter(a,0)
return 1, a [1] (unless a[1]=nil
); second iteration call iter(a,1)
return 2, a [2] …… until the first one. nil
element.
Multi-state iterator
In many cases, iterators need to hold multiple state information instead of simple state constants and control variables. the easiest way is to use closures, and another way is to encapsulate all the state information into table
inside, set table
as the state constant of the iterator, in which case all the information can be stored in the table
so iterative functions usually do not need a second argument.
For the following example, we created our own iterator:
Example
array = {"Google", "Runoob"}
function elementIterator (collection)
local index = 0
local count = #collection
-- closures
return function ()
index = index + 1
if index <= count
then
-- Returns the current element of the iterator
return collection[index]
end
end
end
for element in elementIterator(array)
do
print(element)
end
The output result of the above example is:
Google
Runoob
In the above example, we can see elementIterator
a closure function is used to calculate the size of the collection and output each element.