【发布时间】:2018-10-03 10:34:16
【问题描述】:
(也发布在 Lua 邮件列表中)
所以我一直在编写深拷贝算法,我想测试它们,看看它们是否按我希望的方式工作。虽然我确实可以访问 original->copy 映射,但我想要一个通用的深度比较算法,它必须能够比较表键(表作为键?)。
我的深拷贝算法在这里可用:https://gist.github.com/SoniEx2/fc5d3614614e4e3fe131(它不是很有条理,但有 3 个,一个使用递归调用,另一个使用 todo 表,另一个模拟调用堆栈(以一种非常丑陋但兼容 5.1 的方式))
递归版本:
local function deep(inp,copies)
if type(inp) ~= "table" then
return inp
end
local out = {}
copies = (type(copies) == "table") and copies or {}
copies[inp] = out -- use normal assignment so we use copies' metatable (if any)
for key,value in next,inp do -- skip metatables by using next directly
-- we want a copy of the key and the value
-- if one is not available on the copies table, we have to make one
-- we can't do normal assignment here because metatabled copies tables might set metatables
-- out[copies[key] or deep(key,copies)]=copies[value] or deep(value,copies)
rawset(out,copies[key] or deep(key,copies),copies[value] or deep(value,copies))
end
return out
end
编辑:我发现这样的东西并不能真正将表作为键处理:http://snippets.luacode.org/snippets/Deep_Comparison_of_Two_Values_3(下面是 sn-p 的副本)
function deepcompare(t1,t2,ignore_mt)
local ty1 = type(t1)
local ty2 = type(t2)
if ty1 ~= ty2 then return false end
-- non-table types can be directly compared
if ty1 ~= 'table' and ty2 ~= 'table' then return t1 == t2 end
-- as well as tables which have the metamethod __eq
local mt = getmetatable(t1)
if not ignore_mt and mt and mt.__eq then return t1 == t2 end
for k1,v1 in pairs(t1) do
local v2 = t2[k1]
if v2 == nil or not deepcompare(v1,v2) then return false end
end
for k2,v2 in pairs(t2) do
local v1 = t1[k2]
if v1 == nil or not deepcompare(v1,v2) then return false end
end
return true
end
序列化也不是一种选择,因为序列化的顺序是“随机的”。
【问题讨论】:
-
这里的问题到底是什么?这些有用吗?他们在某些情况下会失败吗?我也不确定我是否完全理解你想要什么。您希望能够将两个任意表相互比较吗?我认为,确保你用尽两边桌子上的钥匙是困难的。
-
@EtanReisner 我没有简单的方法来测试它们是否工作,除了漂亮地打印输入和输出然后手动比较它们。如果我有一种自动化的方法来测试它(也就是深度比较它),我就不必花时间手动检查它是否正常工作......它对于测试套件也很有用......
-
您是要按值还是按内容将表作为键进行比较?函数(作为键或值)呢? C 函数(相同)呢?用户数据(相同)呢?
-
@EtanReisner 我的函数只复制表(到目前为止),所以你可以只使用 == 或 rawequals()。我的主要问题是
{[{}] = {}}。 -
对。在解决问题之前,您需要定义该场景的“平等”意味着什么。所有空表都“相等”吗?这可能是合理的,除非当您需要从原始表中的项目在副本表中查找时它对您没有帮助。
标签: algorithm lua compare equality