Traversing nested tables in lua
我是lua的新手,并且很难使用嵌套数据结构。
我正在尝试编写一个层次结构系统,其中有一个包含三个键的表,而值是另一个表。按照我的特定顺序,三个顶级键是区域,区域和环境。我想使用表中与我的环境变量的键相关的最具体的子值。
因此,鉴于下面的数据和环境变量表,我想返回region.US的键,因为该表中不存在zone变量,尽管如果这样做的话,将是最高优先级。 key region.US确实存在并且比环境具有更高的优先级,因此我应该返回ccc。
根据lua加载表的方式,我通过匹配顶级键的字符串来获得不同的结果。如何在Lua中做到这一点?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
我的代码无法正常工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 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
1 2 3 4 5 6 7 8 9 10 11 12 | ? lua git:(integration) ? lua test1.lua gggg environment: staging: fff prod: eee food: gggg zone: 2: bbbbb 1: aaaaa region: US: ccc EU: ddd |
...
1 2 3 4 5 6 7 8 9 10 11 12 | ? 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | 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) |