如何合并两个表并覆盖两个表中的元素?

发布于 2024-08-01 18:52:18 字数 85 浏览 5 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

杀お生予夺 2024-08-08 18:52:19

这是我根据 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

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
红墙和绿瓦 2024-08-08 18:52:19

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

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

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
羁〃客ぐ 2024-08-08 18:52:19

对于数字索引表合并:

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

For numeric-index table merging:

for k,v in pairs(secondTable) do table.insert(firstTable, v) end
佞臣 2024-08-08 18:52:19

这不能正常工作吗?


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

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
暮年 2024-08-08 18:52:19

我更喜欢 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

感谢这个很好的函数,它应该是表类的一部分,因此您可以调用 a:merge(b) 但执行 table.merge = function(a, b) ... 对我不起作用。 对于真正的书呆子来说,甚至可以压缩成一个衬垫:)

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 :)

苏别ゝ 2024-08-08 18:52:19

对于大多数情况,Doug Currie 的答案是最简单的。 如果您需要更强大的表合并,请考虑使用 Penlight 库中的 merge() 方法。

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

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

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
-- }
谁许谁一生繁华 2024-08-08 18:52:19
for k,v in pairs(t2) do t1[k] = v end

字符串解决方案的关键

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

key for string solution

末が日狂欢 2024-08-08 18:52:19

扩展这个伟大的答案,https://stackoverflow.com/a/1283399/1570165,我想选择一个(纯)函数式方法如下所示:

-- 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 }

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 }

另类 2024-08-08 18:52:19

就像Doug Currie说的,你可以使用他的功能,但是他的方法有问题。 如果 first_tablek 索引中有内容,该函数将覆盖它。

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

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

此解决方案的唯一问题是索引设置为数字,而不是字符串。 这适用于以数字作为索引的表,对于以字符串作为索引的表,请使用 Doug Currie 的方法。

道格·柯里的方法:

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

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
多像笑话 2024-08-08 18:52:18
for k,v in pairs(second_table) do first_table[k] = v end
for k,v in pairs(second_table) do first_table[k] = v end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文