Reputation: 69
I want to copy a simple table however whenever I change the copied table it changes the original table too and it's very bizarre
function tablelength(T)
local count = 0
for _ in pairs(T) do count = count + 1 end
return count
end
board = {}
print("board: "..tablelength(board))
newBoard = board
newBoard[tablelength(newBoard) + 1] = 1
print("board: "..tablelength(board))
newBoard[tablelength(newBoard) + 1] = 1
print("board: "..tablelength(board))
Output:
board: 0
board: 1
board: 2
Upvotes: 1
Views: 750
Reputation: 4602
newBoard = board
only created a new reference newBoard
, second after board
, to the same table, which was creared by {}
.
You need to deep copy a table, if you want a new one.
Something like this:
local function deep_copy( tbl )
local copy = {}
for key, value in pairs( tbl ) do
if type( value ) ~= 'table' then
copy[key] = value
else
copy[key] = deep_copy( value )
end
end
return copy
end
This is a naïve implementation that does not copy metatables and keys that are tables (it's possible in Lua), and tables that include references to themselves, but it's likely to be enough for your purposes.
Further reading: https://www.lua.org/pil/2.5.html, starting from paragraph two.
P.S. A less naïve implementation, based on http://lua-users.org/wiki/CopyTable:
local function deep_copy( original, copies )
if type( original ) ~= 'table' then return original end
-- original is a table.
copies = copies or {} -- this is a cache of already copied tables.
-- This table has been copied previously.
if copies[original] then return copies[original] end
-- We need to deep copy the table not deep copied previously.
local copy = {}
copies[original] = copy -- store a reference to copied table in the cache.
for key, value in pairs( original ) do
local dc_key, dc_value = deep_copy( key, copies ), deep_copy( value, copies )
copy[dc_key] = dc_value
end
setmetatable(copy, deep_copy( getmetatable( original ), copies) )
return copy
end
Upvotes: 1