【问题标题】:One loop for iterating through multiple Lua tables一个循环遍历多个 Lua 表
【发布时间】:2016-02-24 07:17:51
【问题描述】:

是否可以用同一个循环遍历多个 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'

【问题讨论】:

  • 注意:尽管您没有明确表示您期望这样做,但您应该知道键值对以不确定的顺序枚举。 (哦,所有表都是键值表;只是您选择的构造函数语法不同。)
  • 是的,感谢您指出。在我的情况下,顺序并不重要,我只想获取两个表的所有对。

标签: lua iteration lua-table


【解决方案1】:
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 元方法。

【讨论】:

    【解决方案2】:

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

    我假设 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
    

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    【解决方案3】:

    虽然拥有像 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 所要求的。 OP 请求一个循环。
    • 直到现在我都是这样做的,但这并不是说我只是在循环中进行了一次打印,还有更多行,并且我想避免在必须更改某些内容时出现复制粘贴错误。
    • @816 那我建议你把所有的代码放在一个函数里,然后在每次迭代时调用这个函数(还是用两个单独的循环)
    • 是的,这就是两个循环的方式:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-05
    • 2017-11-26
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    相关资源
    最近更新 更多