Lua iterator


Release date:2023-10-08 Update date:2023-10-13 Editor:admin View counts:338

Label:

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 type for 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 used nil 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.

Powered by TorCMS (https://github.com/bukun/TorCMS).