Lua – fusionar tablas?

Necesito fusionar dos tablas, con el contenido del segundo sobreescribiendo contenido en el primero si un elemento dado está en ambos. Miré pero las bibliotecas estándar no parecen ofrecer esto. ¿Dónde puedo obtener tal función?

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

Esto es lo que se me ocurrió basado en la respuesta de Doug Currie:

 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 

¿No funcionaría esto correctamente?

 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 

Para la fusión de tabla de índice numérico:

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

Aquí está la versión iterativa para la fusión profunda porque no me gustan los posibles desbordamientos de stack recursivos.

 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 

La respuesta de Doug Currie es la más simple para la mayoría de los casos. Si necesita una combinación más robusta de tablas, considere usar el método merge() de la biblioteca de Penlight .

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

Preferí la versión de James por su simplicidad y la utilicé en mis utils.lua: agregué un cheque para el tipo de tabla para el manejo de errores.

 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 

Gracias por esta buena función que debería ser parte de la clase de tabla para que pudiera llamar a:merge(b) pero hacer table.merge = function(a, b) ... no funcionó para mí. Incluso podría ser comprimido a un trazador de líneas para los nerds reales 🙂

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

clave para la solución de cadena