How do I iterate through a table starting at a key position in lua?

60 views Asked by At

I am trying to iterate through a table but start from a position in the table using a key.

list = {
  "one",
  "two",
  "four",
  "five",
  "six"
}

for k = 3, v in pairs(list) do
  print("Key:" .. k .. " " .. "Value:" .. v)
end

Compilation error on line 10: ...\ZeroBraneStudio\myprograms\untitled.lua:10: 'do' expected near 'in'

1

There are 1 answers

0
Oka On

For an array-like table (one with a sequence), you can use a numeric for, with the upper bound being the length of the table.

local list = {
    "one",
    "two",
    "four",
    "five",
    "six"
}

for i = 3, #list do
    print(i, list[i])
end
3   four
4   five
5   six

Note that starting with a certain key (index) usually only makes sense given an array-like table - which your list is. The key-value pairs in a table have no stable order as far as next/pairs is concerned (note that ipairs is for operating on a sequence).

If the arbitrary keys in an associative array-like table follow a particular generation order (i.e., they are deterministic), it is possible to iterate through them in a stable way, but that is a specific use-case.


You can also write a function similar in form to ipairs - one that returns an iterator function (alongside the initial state and control) used by the generic for, but starts from a given index.

Here is a cursory example where the iterator returns index, value to be assigned to the loop variables.

local function ipairsfrom(tab, n)
    return function (t, i)
        i = i + 1
        return t[i] ~= nil and i or nil, t[i]
    end, tab, n and n - 1 or 0
end

local list = { 'a', 'b', 'c', 'd', 'e' }

for index, value in ipairsfrom(list, 3) do
    print(index, value)
end
3   c
4   d
5   e

There are many ways to write such an iterator and the function that creates it. For example, returning value, index might be preferred since the value is often more interesting, and allows us to omit the second variable (as opposed to using for _, value in).

local function ipairsfrom(t, i)
    i = i and i - 1 or 0
    return function ()
        i = i + 1
        return t[i], i
    end
end

for value, index in ipairsfrom({ 'a', 'b', 'c' }, 2) do
    print(index, value)
end
2   b
3   c