Easy Tutorial
❮ Lua Functions Lua Goto ❯

Lua Iterators

An iterator is an object that can be used to traverse parts or all of the elements in a standard template library container, with each iterator object representing a specific address within the container.

In Lua, an iterator is a structure that supports pointer types and can traverse each element of a collection.


Generic For Iterator

The generic for internally saves the iteration function, actually storing three values: the iteration function, a state constant, and a control variable.

The generic for iterator provides key/value pairs of the collection, with the syntax as follows:

for k, v in pairs(t) do
    print(k, v)
end

In the above code, k, v is the variable list; pairs(t) is the expression list.

Consider the following example:

Example

array = {"Google", "tutorialpro"}

for key,value in ipairs(array) 
do
   print(key, value)
end

The output of the above code is:

1  Google
2  tutorialpro

In the above example, we used the default iterator function ipairs provided by Lua.

Let's look at the execution process of the generic for:

In Lua, we often use functions to describe iterators, with each call to the function returning the next element of the collection. Lua iterators include the following types:


Stateless Iterators

Stateless iterators are those that do not retain any state, thus allowing us to avoid the extra cost of creating closures in loops by using stateless iterators.

Each iteration, the iteration function is called with two variables (state constant and control variable) as parameters, and a stateless iterator can obtain the next element using only these two values.

A typical simple example of such a stateless iterator is ipairs, which traverses each element of the array, with the element index needing to be numeric.

The following example uses a simple function to implement an iterator that calculates the square of a 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 of the above example is:

1    1
2    4
3    9

The state of the iteration includes the table being traversed (a state constant that does not change during the loop) and the current index (control variable). Both ipairs and the iteration function are simple, and in Lua, we can implement them like this:

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) to start the loop, it obtains three values: the iteration function iter, the state constant a, and the initial value of the control variable 0; then Lua calls iter(a,0) returning 1, a[1] (unless a[1]=nil); the second iteration calls iter(a,1) returning 2, a[2]... until the first nil element.


Stateful Iterators

In many cases, an iterator needs to save multiple state information rather than simple state constants and control variables. The simplest method is to use closures, and another method is to encapsulate all state information into a table, making the table the state constant of the iterator, as this allows all information to be stored in the table, the iteration function usually does not need a second parameter.

The following example creates our own iterator:

Example

array = {"Google", "tutorialpro"}

function elementIterator (collection)
   local index = 0
   local count = #collection
   -- Closure function
   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

The output of the above example is:

Google
tutorialpro

In the above example, we can see that elementIterator uses a closure function to calculate the size of the collection and output each element.

❮ Lua Functions Lua Goto ❯