How to merge two tables overwriting the elements which are in both?

MergeLuaLua Table

Merge Problem Overview


I need to merge two tables, with the contents of the second overwriting contents in the first if a given item is in both. I looked but the standard libraries don't seem to offer this. Where can I get such a function?

Merge Solutions


Solution 1 - Merge

for k,v in pairs(second_table) do first_table[k] = v end

Solution 2 - Merge

Here's what i came up with based on Doug Currie's answer:

function tableMerge(t1, t2)
	for k,v in pairs(t2) do
		if type(v) == "table" then
			if type(t1[k] or false) == "table" then
				tableMerge(t1[k] or {}, t2[k] or {})
			else
				t1[k] = v
			end
		else
			t1[k] = v
		end
	end
	return t1
end

Solution 3 - Merge

Wouldn't this work properly?


function merge(t1, t2)
for k, v in pairs(t2) do
if (type(v) == "table") and (type(t1[k] or false) == "table") then
merge(t1[k], t2[k])
else
t1[k] = v
end
end
return t1
end

Solution 4 - Merge

For numeric-index table merging:

for k,v in pairs(secondTable) do table.insert(firstTable, v) end

Solution 5 - Merge

Doug Currie's answer is the simplest for most cases. If you need more robust merging of tables, consider using the merge() method from the Penlight library.

require 'pl'
pretty.dump(tablex.merge({a=1,b=2}, {c=3,d=4}, true))

-- {
--   a = 1,
--   d = 4,
--   c = 3,
--   b = 2
-- }

Solution 6 - Merge

Here's iterative version for deep merge because I don't like potential stack overflows of recursive.

local merge_task = {}
function merge_to_left_o(orig, new)
   merge_task[orig] = new

   local left = orig
   while left ~= nil do
      local right = merge_task[left]
      for new_key, new_val in pairs(right) do
         local old_val = left[new_key]
         if old_val == nil then
            left[new_key] = new_val
         else
            local old_type = type(old_val)
            local new_type = type(new_val)
            if (old_type == "table" and new_type == "table") then
               merge_task[old_val] = new_val
            else
               left[new_key] = new_val
            end
         end
      end
      merge_task[left] = nil
      left = next(merge_task)
   end
end

Solution 7 - Merge

I preferred James version for its simplicity and use it in my utils.lua - i did add a check for table type for error handling.

function merge(a, b)
    if type(a) == 'table' and type(b) == 'table' then
        for k,v in pairs(b) do if type(v)=='table' and type(a[k] or false)=='table' then merge(a[k],v) else a[k]=v end end
    end
    return a
end

Thanks for this nice function which should be part of the table class so you could call a:merge(b) but doing table.merge = function(a, b) ... did not work for me. Could even be compressed to a one liner for the real nerds :)

Solution 8 - Merge

Like Doug Currie said, you can use his function, but there is a problem with his method. If first_table has things in it's k index, the function will over write it.

I'm assuming you're trying to merge these tables, not overwrite index's and value's. So this would be my method, it's very similar but is used for merging tables.

for _, v in pairs(second_table) do table.insert(first_table, v) end

The only problem with this solution is that the index is set as numbers, not as strings. This will work with tables with numbers as the index, and for tables with strings as their index, use Doug Currie's method.

Doug Currie's method:
for k,v in pairs(second_table) do first_table[k] = v end

Solution 9 - Merge

for k,v in pairs(t2) do t1[k] = v end

key for string solution

Solution 10 - Merge

Extending this great answer, https://stackoverflow.com/a/1283399/1570165, I would like to go with a (pure) functional approach like this one below:

-- example values
local t1 = { a = 0, b = 2 }
local t2 = { a = 1, c = 3 }

-- merge function that takes functional approach

local merge = function(a, b)
	local c = {}
	for k,v in pairs(a) do c[k] = v end
	for k,v in pairs(b) do c[k] = v end
	return c
end

-- t1 and t2 value still same after merge
print(merge(t1, t2)) -- { a = 1, b = 2, c = 3 }
print(t2) -- { a = 1, c = 3 }
print(t1) -- { a = 0, b = 2 }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRCIXView Question on Stackoverflow
Solution 1 - MergeDoug CurrieView Answer on Stackoverflow
Solution 2 - MergeRCIXView Answer on Stackoverflow
Solution 3 - MergeJamesView Answer on Stackoverflow
Solution 4 - MergeJimmy liuView Answer on Stackoverflow
Solution 5 - MergeBlackcoatView Answer on Stackoverflow
Solution 6 - MergeOleg V. VolkovView Answer on Stackoverflow
Solution 7 - Mergehexerei softwareView Answer on Stackoverflow
Solution 8 - MergeMayView Answer on Stackoverflow
Solution 9 - MergeTimChangView Answer on Stackoverflow
Solution 10 - MergeHeechul RyuView Answer on Stackoverflow