816-8055
816-8055

Reputation: 557

One loop for iterating through multiple Lua tables

Is it possible to iterate through multiple Lua tables with the same loop?

For looping through indexed tables I can do something like this:

local t1 = {"a", "b", "c"}
local t2 = {"d", "e", "f"}

local num = #t1+#t2
for i=1, num, do
    local j
    local val
    if i <= #t1 then
        j = i
        val = t1[j]
    else
        j = i-#t1
        val = t2[j]
    end

    -- Do stuff
end

but how about key-value tables?

E.g. something like this:

local t1 = {a="a", b="b", c="c"}
local t2 = {d="d", e="e", f="f"}

for key, val in pairs(t1) or pairs(t2) do
    print(key..":  '"..val.."'")
end

should result in this:

a:  'a'
b:  'b'
c:  'c'
d:  'd'
e:  'e'
f:  'f'

Upvotes: 3

Views: 3837

Answers (3)

Chris Seickel
Chris Seickel

Reputation: 11

For the given example, I think it is much more concise and clear to just wrap the loop in an outer loop that iterates the tables.

I am assuming the primary reason OP was looking for a solution other than two loops was to avoid having to write the inner logic twice. This is a good solution to that problem and only adds two lines of code:

local t1 = {a="a", b="b", c="c"}
local t2 = {d="d", e="e", f="f"}

for _, tbl in ipairs({ t1, t2 }) do
  for key, val in pairs(tbl) do
    print(key..":  '"..val.."'")
  end
end

Upvotes: 1

warspyking
warspyking

Reputation: 3113

While it's always nice to have an iterator like Egor's, a more efficient solution would simply be

local t1 = {a="a", b="b", c="c"}
local t2 = {d="d", e="e", f="f"}

for key, val in pairs(t1) do
    print(key..": "..val)
end
for key, val in pairs(t2) do
    print(key..":  '"..val)
end

It's simple, concise, and easily understandable.

Upvotes: -1

Egor Skriptunoff
Egor Skriptunoff

Reputation: 23727

function pairs(t, ...)
  local i, a, k, v = 1, {...}
  return
    function()
      repeat
        k, v = next(t, k)
        if k == nil then
          i, t = i + 1, a[i]
        end
      until k ~= nil or not t
      return k, v
    end
end

local t1 = {a="a", b="b", c="c"}
local t2 = {d="d", e="e", f="f"}

for key, val in pairs(t1, t2) do
    print(key..":  '"..val.."'")
end

Note: this implementation does not respect __pairs metamethod.

Upvotes: 4

Related Questions