function shallowCopy(t)
if type(t) ~= 'table' then return t end
local result = {}
for k, v in pairs(t) do
result[k] = shallowCopy(v)
end
return result
end
Now let's add another level there: Keys can be tables, too:
function shallowCopy(t)
if type(t) ~= "table" then return t end
local result = {}
for k, v in pairs(t) do
result[shallowCopy(k)] = shallowCopy(v)
end
return result
end
Finally, tables containing loops will make the function loop infinitely. The only way I've found to handle that is to parse the table in advance, looking for loops, and handling those differently than the default tables. But the code to handle that case is a bit long and boring.
Robin wrote:Yes, but it will make a shallow copy of a sequence. If your table contains any non-sequence key/value pairs and you want to copy those too, you'd use:
function shallowCopy(t)
local n = {}
for k, v in pairs(t) do
n[k] = v
end
return n
end
Works considering that the table doesn't have any inner tables (It will work, but will point to the tables of the first list, which may not be the desirable behavior).
One option to duplicate these tables too would be a recursive call, like this:
function shallowCopy(t)
local n = {}
for k, v in pairs(t) do
if type(v) == "table" then
n[k] = shallowCopy(v)
else
n[k] = v
end
end
return n
end
I made this function once. But I made the sub-tables copy thing optional. Instead of making it always copy tables (sometimes I wanted to change those tables, not their copies), I made this:
function shallowCopy(t, sub)
local sub = sub or false
local n = {}
for k, v in pairs(t) do
if type(v) == "table" and sub then
n[k] = shallowCopy(v, true)
else
n[k] = v
end
end
return n
end
kikito wrote:(...)
Finally, tables containing loops will make the function loop infinitely. The only way I've found to handle that is to parse the table in advance, looking for loops, and handling those differently than the default tables. But the code to handle that case is a bit long and boring.
function deepcopy(t, cache)
if type(t) ~= 'table' then
return t
end
cache = cache or {}
if cache[t] then
return cache[t]
end
local new = {}
cache[t] = new
for key, value in pairs(t) do
new[deepcopy(key, cache)] = deepcopy(value, cache)
end
return new
end
This deals correctly with tables forming any graph, not just trees.
Also, neither touches metatables. If you want them metatables, you have to decide if you want to copy those as well, or just do something like setmetatable(new, getmetatable(t)).