How to change the value of one table, and not both tables?

I have a table that I need to make a copy of, and I need to make modifications to the data in the second table without any of these modifications applying to the original table. But I haven’t been able to figure out how to do this.

local t1 = {[Vector3.new(1, 2, 3)] = {1, "2", true, nil, {5, 6, 7}}, [Vector3.new(4, 5, 6)] = {7, "8", true, nil, {9, 10, 11}}} 
print(t1[Vector3.new(4, 5, 6)][1])  -- This prints 7
local t2 = table.clone(t1) 
t2[Vector3.new(4, 5, 6)][1] = 100 
print(t2[Vector3.new(4, 5, 6)][1]) -- This prints 100
print(t1[Vector3.new(4, 5, 6)][1]) -- This one also prints 100, but it's actually only supposed to print 7, because the modification was made to t2, and not t1

In the code, I am setting a value in the table t2 to equal to the value of 100. And on line 5 when I print this value from the table t2, it indeed does print 100, but when we print the value from the same exact index, but on the other table (table t1) on line 6, it also prints 100. What is happening? Why does this happen? This doesn’t make sense? I expect it to print 7 when printing it from table t1, but instead it prints 100.

I apologize for the strange keys in these dictionaries, but for the tables that I am having this issue in, I need to use Vector3.new(x, y, z) keys for the table that I am having issues with.

table.clone() should be returning an entirely seperate table, so I’m unsure why it’s not.

Can you please quickly just check if t1 == t2?


Given that cloning didn’t function as intended, you may need to make use of a for loop or two, in order to create the new table. Assuming that the table is only a dictionary and has no indexed components, then this should work

local t1 = {...}
local t2 = {}

for key, val in pairs(t1) do
    t2[key] = val
end

print(t1)
print(t2)
1 Like

I’m not sure if this is what you wanted me to do, but I literally just did t1 == t2 in the console, and it does print false.

Edit:

Let me check real quick.

Hm. That indicates that they are indeed seperate. It’s possible that it’s behaving this way due to it being a dictionary, instead of an array. Does the code in the second half of my original reply resolve the issue?

1 Like

What is weird is after running it, t1, and t2 still got changed.

local t1 =  {[1] = {1, 4}, [2] = {5, 6}}
local t2 = {}

for key, val in pairs(t1) do
	t2[key] = val
end

print(t1) -- prints the table
print(t2) -- prints the table

print(t1[2][2]) -- 6
t2[2][2] = 1 
print(t2[2][2]) -- 1
print(t1[2][2]) -- 1

you need to implement a deep copy function that recursively copies all nested tables. Here’s how you can do it:

Deep Copy Function:

function deepCopy(orig)
    local origType = type(orig)
    local copy
    if origType == 'table' then
        copy = {}
        for origKey, origValue in next, orig, nil do
            copy[deepCopy(origKey)] = deepCopy(origValue)
        end
        setmetatable(copy, deepCopy(getmetatable(orig)))
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end

You can put this into usage later on

1 Like

This actually fixes my problem, thanks.

But, out of curiosity, what is the reason that this works, and my previous attempts at getting this to work don’t work? How is a deep copy any different than doing what I was doing?

Ah, that explains it.

Why Your Previous Attempts Didn’t Work:

Your initial attempt using table.clone performed a shallow copy, which means that:

  • The top-level keys and values were copied directly.
  • The nested tables were not duplicated but merely referenced.

Because of this, both t1 and t2 shared the same nested tables, leading to unintended side effects when modifying one of the tables.

  1. Shallow Copy:

    • Copies only the top-level elements.
    • Nested tables are shared between the original and the copied table.
    • Changes to nested tables in the copy affect the original.
  2. Deep Copy:

    • Recursively copies all elements, including nested tables.
    • Nested tables are independent between the original and the copied table.
    • Changes to nested tables in the copy do not affect the original.
1 Like

I got mixed up with what the difference between a shallow copy and deep copy was xD

No worries! The distinction between shallow and deep copies can be a bit mixed up

To summarize again briefly:

  • Shallow Copy: Only the first level of the structure is copied. Nested objects or tables are still referenced, not duplicated.
  • Deep Copy: An entire independent copy of the structure is created, including all nested objects or tables.
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.