【问题标题】:Traversing nested tables in lua遍历lua中的嵌套表
【发布时间】:2018-11-21 10:42:08
【问题描述】:

我是 lua 新手,很难使用嵌套数据结构。

我正在尝试编写一个层次结构系统,其中我有一个包含三个键的表,而值是另一个表。三个顶级键是区域、区域和环境,按我的具体顺序排列。我想使用表中与我的环境变量的键相关的最具体的子值。

因此,鉴于下面的数据和环境变量表,我想返回 region.US 的键,因为表中不存在 zone 变量,尽管如果它存在,那将是重中之重。关键 region.US 确实存在,并且优先级高于环境,因此我应该返回 ccc。

根据 lua 加载表格的方式,我通过匹配顶级键的字符串得到不同的结果。如何在 Lua 中做到这一点?

env_zone = 5  -- doesn't exist in table, but should return if it did
env_region = US  -- exists and should return because env_zone doesn't exist
env_environment = food  -- does exist but should not be returned because env_region is a higher priority


zone:
  1: aaaaa
  2: bbbbb
region:
  EU: ddd
  US: ccc
environment:
  food: gggg
  prod: eee
  staging: fff

我的代码不能正常工作。

local cjson = require('cjson')

function tprint (tbl, indent)
  if not indent then indent = 0 end
  for k, v in pairs(tbl) do
    formatting = string.rep("  ", indent) .. k .. ": "
    if type(v) == "table" then
      print(formatting)
      tprint(v, indent+1)
    elseif type(v) == 'boolean' then
      print(formatting .. tostring(v))
    else
      print(formatting .. v)
    end
  end
end

local function slurp(path)
    local f = io.open(path)
    local s = f:read("*a")
    f:close()
    return s
end

local json_string = slurp("data.json")
local tab = cjson.decode(json_string)

local zone_var = os.getenv("zone")   -- "fake"
local region_var = os.getenv("region") -- "US"
local env_var = os.getenv("env")     -- "food"

local ok, err = pcall(
  function ()
    for key, value in pairs(tab) do
      if string.match(key, "zone") then --highest priority, check it first
        for subkey, subvalue in pairs(value) do
          if string.match(subkey, zone_var) then
            print(subvalue)
            return
          end
        end
      elseif string.match(key, "region") then --second highest priority
        for subkey, subvalue in pairs(value) do
          if string.match(subkey, region_var) then
            print(subvalue)
            return
          end
        end
      elseif string.match(key, "environment") then --last chance
        for subkey, subvalue in pairs(value) do
          if string.match(subkey, env_var) then
            print(subvalue)
            return
          end
        end
      end
    end
  end
)
tprint(tab)

输出:应该总是返回 ccc

➜  lua git:(integration) ✗ lua test1.lua
gggg
environment:
  staging: fff
  prod: eee
  food: gggg
zone:
  2: bbbbb
  1: aaaaa
region:
  US: ccc
  EU: ddd

...

➜  lua git:(integration) ✗ lua test1.lua
ccc
zone:
  1: aaaaa
  2: bbbbb
region:
  EU: ddd
  US: ccc
environment:
  food: gggg
  prod: eee
  staging: fff

【问题讨论】:

    标签: lua lua-table


    【解决方案1】:

    我花了这么长时间才弄清楚这一点,我感到非常尴尬。 :/

    local cjson = require('cjson')
    
    function tprint (tbl, indent)
      if not indent then indent = 0 end
      for k, v in pairs(tbl) do
        formatting = string.rep("  ", indent) .. k .. ": "
        if type(v) == "table" then
          print(formatting)
          tprint(v, indent+1)
        elseif type(v) == 'boolean' then
          print(formatting .. tostring(v))
        else
          print(formatting .. v)
        end
      end
    end
    
    local function slurp(path)
        local f = io.open(path)
        local s = f:read("*a")
        f:close()
        return s
    end
    
    local json_string = slurp("data.json")
    local tab = cjson.decode(json_string)
    
    local zone_var = os.getenv("zone")
    local region_var = os.getenv("region")
    local env_var = os.getenv("environment")
    
    local ok, err = pcall(
      function()
        for key, value in pairs(tab.zone) do
          if string.match(key, zone_var) then
            print(value)
            return
          end
        end
        for key, value in pairs(tab.region) do
          if string.match(key, region_var) then
            print(value)
            return
          end
        end
        for key, value in pairs(tab.environment) do
          if string.match(key, environment_var) then
            print(value)
            return
          end
        end
      end
    )
    
    tprint(tab)
    

    【讨论】:

      猜你喜欢
      • 2016-06-03
      • 2020-06-26
      • 2019-08-22
      • 2011-09-02
      • 2011-05-15
      • 2012-11-11
      • 1970-01-01
      • 2016-07-29
      相关资源
      最近更新 更多