一个循环遍历多个 Lua 表

One loop for iterating through multiple Lua tables

是否可以使用相同的循环遍历多个 Lua 表?

为了遍历索引表,我可以这样做:

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

但是键值表呢?

例如像这样:

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

结果应该是这样的:

a:  'a'
b:  'b'
c:  'c'
d:  'd'
e:  'e'
f:  'f'
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

注意:此实现不遵循 __pairs 元方法。

虽然有一个像 Egor 那样的迭代器总是很好,但更有效的解决方案只是

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

简明扼要,通俗易懂。

对于给定的示例,我认为将循环包装在迭代表的外部循环中会更加简洁明了。

我假设 OP 寻找两个循环以外的解决方案的主要原因是避免必须两次编写内部逻辑。这是解决该问题的好方法,只添加了两行代码:

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