I have a data structure of nested tables that can be N deep. for example
local data = {
[1] = {
[1] = { "stuff" },
[2] = {
[1] = { "stuff" },
[2] = { "more stuff" },
[3] = {
[1] = "deeper stuff"
}
}
}
Now I can reference "deeper stuff" via data[2][3][1] But is there a way that I can store the 2-3-1 as a key so I can reference this data[key] ?
I am storing a set of actions that are transformed and looped over in a denormalised table. I want to be able to reference that this particular action came from a specific point in the original data table. As this is n levels deep is there a dynamic way of writing [2][3][1]...[n]?
You cannot have a single multi-dimensional key. The only way to achieve something like that would be to have some string like "2-3-1"
which you then use in an __index
metamethod that tranlates it to the separate keys.
setmetatable(data, {
__index = function(t, k)
for index in k:gmatch("%d+") do
-- insert fancier error handling here
if not t then error("attempt to index nil") end
t = rawget(t, tonumber(index))
end
return t
end
})
print(data["2-3-1"]
Alternatively you use a table as key
setmetatable(data, {
__index = function(t, k)
for i,v in ipairs(k) do
if not t then error("attempt to index nil") end
t = rawget(t, v)
end
return t
end
})
print(data[{2,3,1}]
There are of course more ways to implement the table access in __index.
If data is global you could also use load
and do something like
local k = string.gsub("1-1-1", "(%d+)%-?", "[%1]")
local element = load("return data .. k")()
But please don't make data global just so you can do this.
Or you write a function that does that without using metamethods as Egor suggested...