Lua中如何通过定位表操作维度不确定的多维嵌套table
解决方案
方案1:独立工具函数(无侵入,无需修改原表结构)
无需修改原嵌套表的元表,对原有逻辑无影响,适用所有场景:
-- 嵌套表取值函数 function get_nested(t, loc) local current = t for _, idx in ipairs(loc) do current = current[idx] if current == nil then break end end return current end -- 嵌套表赋值函数 function set_nested(t, loc, value) local current = t -- 遍历到倒数第一层节点 for i = 1, #loc - 1 do local idx = loc[i] -- 可选逻辑:中间节点不存在时自动创建空表,不需要可删除改为抛错 if type(current[idx]) ~= 'table' then current[idx] = {} end current = current[idx] end current[loc[#loc]] = value end
用法示例
-- 注意不要用table作为变量名,会覆盖Lua原生全局table工具库 local t = { '1', { '2.1', '2.2' }, { { '3.1.1', '3.1.2' }, '3.2' }, } local loc = {3, 1, 2} print(get_nested(t, loc)) -- 输出 3.1.2 set_nested(t, loc, {'3.1.2.1', '3.1.2.2'}) print(get_nested(t, {3,1,2,1})) -- 输出 3.1.2.1
方案2:元表实现(支持你期望的t[loc]语法)
通过为嵌套表设置元表,直接支持用定位表作为索引的读写语法:
local nested_mt = { __index = function(t, k) -- 索引为表类型时按定位规则取值 if type(k) == 'table' then local current = t for _, idx in ipairs(k) do current = current[idx] if current == nil then break end end return current end -- 普通索引走默认逻辑 return rawget(t, k) end, __newindex = function(t, k, v) -- 索引为表类型时按定位规则赋值 if type(k) == 'table' then local current = t for i = 1, #k - 1 do local idx = k[i] -- 可选逻辑:自动创建不存在的中间节点 if type(current[idx]) ~= 'table' then current[idx] = {} end current = current[idx] end rawset(current, k[#k], v) return end -- 普通索引走默认逻辑 rawset(t, k, v) end }
用法示例
local t = setmetatable({ '1', { '2.1', '2.2' }, { { '3.1.1', '3.1.2' }, '3.2' }, }, nested_mt) local loc = {3, 1, 2} print(t[loc]) -- 输出 3.1.2 t[loc] = {'3.1.2.1', '3.1.2.2'} print(t[3][1][2][1]) -- 输出 3.1.2.1
注意事项
- 不要使用
table作为自定义变量名,会覆盖Lua全局table工具库,导致table.insert、table.concat等原生方法失效。 - 如果需要所有内层嵌套表也支持
[loc]方式访问,可递归遍历所有子表并为其设置相同的元表即可。 - 若不需要自动创建不存在的中间层级节点,可删除
__newindex中的空表自动创建逻辑,改为判断节点不存在时抛出异常即可。
内容的提问来源于stack exchange,提问作者molevision
相关产品推荐
相关产品推荐

