So I am currently playing with tables, and i wanted to see if I could make it have another tables with other keys, get placed into another table that doesn have the same keys, so I can change them accordingly while maintaining their values.
Simply: I’m updating table keys to match another table, as in if one of the table is outdated with missing keys and tables, It would update using the provided table.
Would this work for updating a table?
-- pt = "primary table"
-- ct = "Comparing table"
function update(pt, ct)
for i,v in ct do -- iterates through campring table
if pt[i] == nil then -- if value does not exist
pt[i] = v -- adds value to table
end
if type(v) == "table" then -- if value is a table
update(v, ct[i]) -- Recusive?
end
end
for i,v in pt do -- iterates through primary table
if ct[i] == nil then -- if value inside table doesnt exist
pt[i] = ct[i] -- updates to comparing table value (i think I can just say 'nil' here but idk)
end
if type(v) == "table" then -- if value is a table
update(pt, ct[i]) -- Recursive?
end
end
end
So far It appears to be working properly, but I’m not sure if I’m doing it efficiently or If I made any mistakes in it.
-- test tables
local t = {
H = {"hello"};
Z = {"Hi"};
}
local ct = {
H = {"hello"};
I = {"Hi"};
}
print(t, ct) -- prints fine
update(t, ct) -- error line (technically line 20)
print(t)
Since in both loops, you did not check whether or not ct[i] or pt[i] is nil, you’re basically calling update like update(v, nil) whenever ct[i] or pt[i] is actually empty.
From first loop, edit:
if typeof(v) == "table" then -- if value is a table
if (pt[i] == nil) or not (typeof(pt[i]) == "table") then
pt[i] = {} -- Overwrite to empty table to allow update to fill all missing details.
end
update(v, pt[i]) -- Recusive?
end
Checking if the other table’s index is nil also applies to the second loop.
Not sure if this is how you want it to do:
Check the contents of the comparison table.
Any new index from the comparison table will be inserted to the primary table.
Check the contents of the primary table.
Remove any content from the primary table that does not exist in the comparison table.
This is my revision:
-- test tables
local t = {
H = {"hello"};
Z = {"Hi"};
}
local ct = {
H = {"hello"};
I = {"Hi"};
}
-- pt = "primary table"
-- ct = "Comparing table"
function deep_clone(t)
local clone = {}
for index, item in t do
if typeof(item) == "table" then
clone[index] = deep_clone(item)
continue
end
clone[index] = item
end
return clone
end
function update(pt, ct)
local old_pt = deep_clone(pt)
for i,v in ct do -- iterates through campring table
warn(i, v)
if pt[i] == nil then -- if value does not exist
pt[i] = v -- adds value to table
end
if typeof(v) == "table" then -- if value is a table
if not (typeof(pt[i]) == "table") then
pt[i] = {} -- Overwrite to empty table to allow update to fill all missing details.
end
update(pt[i], v) -- Recusive?
end
end
for i,v in old_pt do -- iterates through primary table
if ct[i] == nil then -- if value inside table doesnt exist
pt[i] = nil -- simply set to nil
continue
end
end
end
print(t, ct) -- prints fine
update(t, ct)
print(t)
print(ct)
I introduced a function called “deep_clone”, which creates a complete duplicate of a table (useful with nested tables) so the original state of the primary table can then be used as a reference for the second loop.
If I recall correctly, table.clone creates a shallow copy of a table. The difference is that a deep copy duplicates all nested tables. Shallow copy does not, and only duplicates values on the root level of a table. Its child tables only get their reference passed (any change to a child table will reflect on all references of it).
If the value doesn’t exist and it is a table you should deep_clone it:
for i,v in ct do -- iterates through campring table
warn(i, v)
if pt[i] == nil then -- if value does not exist
if typeof(v) == "table" then
pt[i] = deep_clone(v)
else
pt[i] = v -- adds value to table
end
else
if typeof(v) == "table" then -- if value is a table
if not (typeof(pt[i]) == "table") then
pt[i] = {} -- Overwrite to empty table to allow update to fill all missing details.
end
update(pt[i], v) -- Recusive?
end
end
end
It’s not that, I mean that the function see’s the table inside the function arguments as nil, and not a table, which is odd because the variables prior to firing are referenced.
If the function sees the parameter as nil, then you’re sending a nil value. There is no way a parameter will be interpreted as nil by the function unless it really is nil.
It’s not a problem with how the language works, it’s a problem within the code.
The function isnt repeating as I added a print to check if it was actually repeating, and it wasn’t as it only print once before the error.
Output:
-- prints prior to function
09:41:25.227 ▶ {...} ▶ {...} - Server - Script:44
-- function fired
09:41:25.228 ▶ {...} ▶ {...} - Server - Script:2
09:41:25.228 E - Server - Script:4 -- print function
09:41:25.228 ▶ {...} ▶ {...} - Server - Script:2 -- tables printed
-- error
09:41:25.228 'Workspace.Script:3: attempt to iterate over a nil value' - Server - Script:3
Edit: nevermind, it is actually only repeating once before the error.
The prints are giving me a nil value inside the tables, and now I’m not sure how to fix them, I have checked if the table wasn’t nil, but somehow it doesnt work.
(Whoops, accidental reply)