Iterators

Iterators provide a way to traverse data. Iterators will usually use a closure to keep track of what data it's on and uses that to determine what to give next.

Take the iterator ipairs for example, it traverses a table in sequence. Its implementation can be written like this:

function ipairs(t)
    local index = 0
    return function()
       index = index + 1
       if t[index] then -- check if the value exists
           return index, t[index] -- key, value
       end
       return nil 
    end
end

local t = {1, 2, 3}
for k, v in ipairs(t) do
    print(k, v)
end
Output:
1 1
2 2
3 3

Using closures, you can define your own way to iterate through a set of data. You could iterate half of it forward and half of it backwards, iterate the entire thing in reverse, iterate every 2 values, etc.

Here's what a reverse ipairs would look like:

function revipairs(t)
    local index = #t + 1 -- start at the last index in the table, +1 to make sure it hits the end value when index-1 happens
    return function()
        index = index - 1 -- travel backwards from the end
        if t[index] then -- again, checking if the value exists
            return index, t[index]
        end
        return nil
    end
end

local t = {1, 2, 3}
for k, v in revipairs(t) do
    print(k, v)
end
Output:
3 3
2 2
1 1

Last updated