Lua – fusionner les tables?

Je dois fusionner deux tables, avec le contenu du deuxième contenu de remplacement dans le premier si un élément donné est dans les deux. J’ai regardé mais les bibliothèques standard ne semblent pas offrir cela. Où puis-je obtenir une telle fonction?

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

Voici ce que j’ai trouvé sur la base de la réponse 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 

Cela ne fonctionnerait-il pas correctement?

 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 

Pour la fusion de la table d’index numérique:

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

Voici une version itérative pour la fusion profonde car je n’aime pas les débordements de stack récursifs potentiels.

 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 réponse de Doug Currie est la plus simple dans la plupart des cas. Si vous avez besoin d’une fusion plus robuste des tables, envisagez d’utiliser la méthode merge() de la bibliothèque Penlight .

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

J’ai préféré la version James pour sa simplicité et je l’ai utilisée dans mes utils.lua – j’ai ajouté une vérification du type de table pour la gestion des erreurs.

 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 

Merci pour cette belle fonction qui devrait faire partie de la classe de la table afin que vous puissiez appeler a:merge(b) mais faire table.merge = function(a, b) ... ne fonctionnait pas pour moi. Pourrait même être compressé à un seul paquebot pour les vrais nerds 🙂

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

clé pour solution de chaîne