遍历lua中的嵌套表

时间:2018-06-12 06:13:16

标签: lua lua-table

我是lua的新手,并且很难处理嵌套数据结构。

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

所以给定下面的数据和环境变量表,我想返回region.US的密钥,因为表中不存在zone变量,尽管如果这样做将是最高优先级。关键区域.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

1 个答案:

答案 0 :(得分:0)

我非常尴尬,我花了很长时间才想到这一点。 :/

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)