Merge Lua-如何合并两个表,覆盖两个表中的元素?

Merge Lua-如何合并两个表,覆盖两个表中的元素?,merge,lua,lua-table,Merge,Lua,Lua Table,我需要合并两个表,如果两个表中都有给定的项,则第二个表的内容将覆盖第一个表的内容。我看了一下,但标准库似乎没有提供这种功能。从哪里可以得到这样的函数?以下是我根据Doug Currie的答案得出的结论: for k,v in pairs(second_table) do first_table[k] = v end function tableMerge(t1, t2) for k,v in pairs(t2) do if type(v) == "table" then

我需要合并两个表,如果两个表中都有给定的项,则第二个表的内容将覆盖第一个表的内容。我看了一下,但标准库似乎没有提供这种功能。从哪里可以得到这样的函数?

以下是我根据Doug Currie的答案得出的结论:

for k,v in pairs(second_table) do first_table[k] = v end
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

这不正常吗


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

这里是深度合并的迭代版本,因为我不喜欢递归的潜在堆栈溢出

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

道格·柯里的答案在大多数情况下是最简单的。如果需要更强大的表合并,请考虑使用库中的方法。


我更喜欢James版本,因为它简单,并在我的utils.lua中使用它-我确实添加了一个检查表类型以进行错误处理

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
感谢这个漂亮的函数,它应该是table类的一部分,这样您就可以调用
a:merge(b)
,但是执行
table.merge=function(a,b)…
对我来说不起作用。甚至可以压缩成一行,以满足真正的书呆子:)


用于字符串解决方案的键

用于数字索引表合并:

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

正如Doug Currie所说,您可以使用他的函数,但他的方法存在问题。如果
first\u表
在其
k
索引中有内容,则函数将重写它

我假设您正在尝试合并这些表,而不是覆盖索引和值。这就是我的方法,非常类似,但用于合并表

成对插入(第二个表)do表。插入(第一个表,v)结束
此解决方案的唯一问题是索引设置为数字,而不是字符串。这将适用于以数字作为索引的表,对于以字符串作为索引的表,使用Doug Currie的方法

Doug Currie的方法:
对于k,v成对(第二个_表)do first_表[k]=v end

wait,这会捕获字符串键等吗?这应该可以通过一些调整来处理子表。谢谢如果索引与数组中的索引相同,那么这不会覆盖表中当前的内容吗?如果有两个表的数字键[1]、[2]、[3]等,其中一个表中已经有数据,您只需迭代第二个表的键,也就是[1]、[2]、[3]等,然后使用相同的键将相同位置的数据添加到表1中,您将覆盖最初存在的数据。你可以用first_table[#first_table+k]=v来解决这个问题。就我个人而言,我会使用tables.insert()来实现这一点,尽管我不确定它在2009年是否可用!在99%的情况下,这将是正确的解决方案,但请记住,在具有引用其他表的表的应用程序中(这在面向对象模式中很常见),您可能需要进行额外的簿记。例如,如果由于某种原因,给定的表可能会直接引用自身,那么您需要检查
v==second\u table
,如果是这样,则指定
first\u table
。表也可以间接引用它们自己,但这可能是一本书中值得解决的问题。“我只是想把这件事放在雷达上,所以,”努夫说。“阿斯特里达克斯这就是提问者所要求的。没有单一的方法可以做到这一点。”。您是在比较表中的键还是值?键/值是否可能是其他表?…我不需要任何类型的比较,但我需要子表…请注意,将标准Lua“名称空间”(如table.*)弄乱通常不是一个好主意。最好自己做。“如果不是t1[k],那么t1[k]={}end”包含一个微妙的bug(找到它!)最好写为“t1[k]=t1[k]或{}”。另外,如果t2[k]是一个表,但t1[k]存在但不是一个表,会发生什么?最后,“table1[k]=v”应该是“t1[k]=v”。是的,但如果你看一下RCIX的原始帖子,其中有一些不同的逻辑,后来被简化为两个相同的
else
语句。我的评论是要讽刺的:如果你因为害怕/预期堆栈溢出而逃避递归;然后不要检查您的任务容器是否溢出内存,那么首先逃逸递归就没有多大意义。@Irfy,用于Lua中的表或其他语言中类似结构的“常规”内存通常比调用堆栈空间更丰富。当然,我们应该考虑哪种解决方案适合于特定的环境,而不仅仅是盲目地复制/粘贴一个或另一个。第三个参数是什么?BTW?第三个参数确定表是如何合并的:<代码>真/ <代码>。
for k,v in pairs(t2) do t1[k] = v end
for k,v in pairs(secondTable) do table.insert(firstTable, v) end