I want to be able to access and edit values in a user-generated table, that can have any number of dimensions.
Say, for this nested table,
table = {
'1',
{
'2.1',
'2.2'
},
{
{
'3.1.1',
'3.1.2'
},
'3.2'
},
}
I would have another table that contains a location for the needed data,
loc = {3, 1, 2}
Ideally, what I'd want is to be able to not only access but edit the values in the table, similar to using table[3][1][2]
but by utilizing the loc
table,
print(table[loc[1]][loc[2]][loc[3]]) --returns 3.1.2
print(table[loc]) --hypothetically something like this that takes each indexed member of the table in order
I also want to be able to edit this table.
table[loc] = {'3.1.2.1', '3.1.2.2'}
I need to be able to edit the global table, so cannot use the methods listed in this reddit thread, and haven't been able to find the right way to use metatables for this yet. I appreciate the help, thanks.
I think you could simply write an additional function for this purpose.
function TreeGetValue (Tree, Location)
local CorrectTree = true
local Index = 1
local Dimensions = #Location
local SubTable = Tree
local Value
-- Find the most deep table according to location
while (CorrectTree and (Index < Dimensions)) do
local IndexedValue = SubTable[Location[Index]]
if (type(IndexedValue) == "table") then
SubTable = IndexedValue
Index = Index + 1
else
CorrectTree = false
end
end
-- Get the last value, regarless of the type
if CorrectTree then
Value = SubTable[Location[Index]]
end
return Value
end
Here, we assume that the tree is well-formatted as the beginning. If we find any problem we set the flag CorrectTree
to false in order to stop immediately.
We need to make sure we have a table
at every dimension in order index a value from.
> TreeGetValue(table, loc)
3.1.2
Obviously, it's also easy to to write the set
function:
function TreeSetValue (Tree, Location, NewValue)
local Index = 1
local Dimensions = #Location
local SubTable = Tree
-- Find the most deep table according to location
while (Index < Dimensions) do
local IndexedValue = SubTable[Location[Index]]
-- Create a new sub-table if necessary
if (IndexedValue == nil) then
IndexedValue = {}
SubTable[Location[Index]] = IndexedValue
end
SubTable = IndexedValue
Index = Index + 1
end
-- Set or replace the previous value
SubTable[Location[Index]] = NewValue
end
And then to test it with your test data:
> TreeGetValue(table, loc)
3.1.2
> TreeSetValue(table, loc, "NEW-VALUE")
> TreeGetValue(table, loc)
NEW-VALUE