Search code examples
lualua-table

How do you copy a Lua table by value?


Recently I wrote a bit of Lua code something like:

local a = {}
for i = 1, n do
   local copy = a
   -- alter the values in the copy
end

Obviously, that wasn't what I wanted to do since variables hold references to an anonymous table not the values of the table themselves in Lua. This is clearly laid out in Programming in Lua, but I'd forgotten about it.

So the question is what should I write instead of copy = a to get a copy of the values in a?


Solution

  • To play a little readable-code-golf, here's a short version that handles the standard tricky cases:

    • tables as keys,
    • preserving metatables, and
    • recursive tables.

    We can do this in 7 lines:

    function copy(obj, seen)
      if type(obj) ~= 'table' then return obj end
      if seen and seen[obj] then return seen[obj] end
      local s = seen or {}
      local res = setmetatable({}, getmetatable(obj))
      s[obj] = res
      for k, v in pairs(obj) do res[copy(k, s)] = copy(v, s) end
      return res
    end
    

    There is a short write-up of Lua deep-copy operations in this gist.

    Another useful reference is this Lua-users wiki page, which includes an example on how to avoid the __pairs metamethod.