Skip to content

Instantly share code, notes, and snippets.

@cpeosphoros
Last active August 24, 2017 16:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cpeosphoros/0aa286c6b39c1e452d9aa15d7537ac95 to your computer and use it in GitHub Desktop.
Save cpeosphoros/0aa286c6b39c1e452d9aa15d7537ac95 to your computer and use it in GitHub Desktop.
Lua Deepcopy with table recursion
local function deepCopy(value, cache, promises, copies)
cache = cache or {}
promises = promises or {}
copies = copies or {}
local copy
if type(value) == 'table' then
if(cache[value]) then
copy = cache[value]
else
promises[value] = promises[value] or {}
copy = {}
for k, v in next, value, nil do
local nKey = promises[k] or deepCopy(k, cache, promises, copies)
local nValue = promises[v] or deepCopy(v, cache, promises, copies)
copies[nKey] = type(k) == "table" and k or nil
copies[nValue] = type(v) == "table" and v or nil
copy[nKey] = nValue
end
local mt = getmetatable(value)
if mt then
setmetatable(copy, mt.__immutable and mt or deepCopy(mt, cache, promises, copies))
end
cache[value] = copy
end
else -- number, string, boolean, etc
copy = value
end
for k, v in pairs(copies) do
if k == cache[v] then
copies[k] = nil
end
end
local function correctRec(tbl)
if type(tbl) ~= "table" then return tbl end
if copies[tbl] and cache[copies[tbl]] then
return cache[copies[tbl]]
end
local new = {}
for k, v in pairs(tbl) do
local oldK = k
k, v = correctRec(k), correctRec(v)
if k ~= oldK then
tbl[oldK] = nil
new[k] = v
else
tbl[k] = v
end
end
for k, v in pairs(new) do
tbl[k] = v
end
return tbl
end
correctRec(copy)
return copy
end
return deepCopy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment