Lua iterator
An iterator is an object that can be used to traverse some or all elements in a standard template library container. Each iterator object represents a certain address in the container
In Lua, an iterator is a structure that supports pointer types, which can traverse each element of a collection.
Generic for iterator
Generic for saves the iteration function internally. In fact, it saves three values: iteration function, state constant, and control variable.
The generic for iterator provides the key/value pair of the collection. The syntax format is as follows:
for k, v in pairs(t) do print(k, v) end
In the above code, k, v are variable lists; pair(t) is an expression list .
View the following example:
array = {"Lua", "Tutorial"} for key,value in ipairs(array) do print(key, value) end
The execution output of the above code is:
1 Lua 2 Tutorial
In the above example we used the iteration function ipairs provided by Lua by default.
Let’s take a look at the execution process of normative for:
First, initialize and calculate the value of the expression after in. The expression should return what normative for requires. Three values: iteration function, state constant, control variable; just like multi-valued assignment, if the number of results returned by the expression is less than three, it will be automatically filled with nil, and the excess will be ignored.
Second, call the iteration function with the state constant and control variable as parameters (note: for the for structure, the state constant is of no use, only get its value during initialization and pass it to the iterative function).
Third, assign the value returned by the iteration function to the variable list.
Fourth, if the first value returned is nil, the loop ends, otherwise the loop body is executed.
Fifth, go back to the second step and call the iteration function again
. In Lua, we often use functions to describe iterators. Each time the function is called, the next element of the collection is returned. Lua's iterators include the following two types:
Stateless iterator
Multi-state iterator
Stateless iterator
Stateless iterator refers to an iterator that does not retain any state, so in a loop we can use stateless iterators to avoid creating closures Cost extra.
Each iteration, the iteration function is called with the values of two variables (state constants and control variables) as parameters. A stateless iterator only uses these two values to obtain the next element.
The typical simple example of this kind of stateless iterator is ipairs, which traverses each element of the array.
In the following example, we use a simple function to implement the iterator and realize the square of the number n:
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 status of the iteration includes The traversed table (status constant that does not change during the loop) and the current index subscript (control variable), ipairs and iteration functions are very simple. We can implement it in Lua like this:
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) to start the loop, it gets three values: iterative function iter, state constant a, and control variable initial value 0; then Lua calls iter(a,0) to return 1, a[1 ] (unless a[1]=nil); the second iteration calls iter(a,1) to return 2, a[2]... until the first nil element.
Multi-state iterator
In many cases, iterators need to save multiple state information instead of simple state constants and control variables. The simplest way is to use closures , and another method is to encapsulate all status information into a table and use the table as the status constant of the iterator. Because in this case all the information can be stored in the table, the iteration function usually does not require a second parameter. .
We created our own iterator in the following example:
array = {"Lua", "Tutorial"} function elementIterator (collection) local index = 0 local count = #collection -- 闭包函数 return function () index = index + 1 if index <= count then -- 返回迭代器的当前元素 return collection[index] end end end for element in elementIterator(array) do print(element) end
The output result of the above example is:
Lua Tutorial
In the above example we can As you can see, the closure function is used in elementIterator to calculate the size of the set and output each element.