Lua 中比较具有表作为键的表格
2017-10-14 23:32:27
收藏:0
阅读:97
评论:3
我需要比较两个表格是否相等-即具有相同的内容。两个表格都具有表格键。
例如:
t1 = {{1,1},{2,2}}
t2 = {{1,1},{2,2}}
t3 = {{1,1},{2,2},{3,3}}
t1 和 t2 应该相等,但是 t1 和 t3 应该不相等。
点赞
用户736889
另一种方法是按照 Programming in Lua 所示的方式序列化两个表。这将生成一个字符串集合的输出,当运行时,它们会重新创建表。将序列化器的输出存储在一个表中,而不是输出它们进行比较。
一旦两个表都序列化为字符串集合,比较表 A 的所有行与表 B 的所有行,并消除它们之间的任何重复将变得简单。如果在处理表 A 结束时,在表 A 或表 B 中有任何行剩余,则它们不相等。
将表序列化为字符串表的代码(修改自 PIL),并比较两个表 a 和 b:
function basicSerialize (o)
if type(o) == "number" then
return tostring(o)
else -- assume it is a string
return string.format("%q", o)
end
end
function save (name, value, saved, output)
saved = saved or {} -- 初始值
output = output or {} -- 初始值
if type(value) == "number" or type(value) == "string" then
table.insert (output, name .. " = " .. basicSerialize(value))
elseif type(value) == "table" then
if saved[value] then -- 已保存该值?
table.insert (output, name .. " = " .. saved[value]) -- 使用它的先前名称
else
saved [value] = name -- 保存名称以供下一次使用
table.insert (output, name .. " = {}") -- 创建一个新表
for k,v in pairs(value) do -- 保存其字段
local fieldname = string.format("%s[%s]", name, basicSerialize(k))
save (fieldname, v, saved, output)
end
end
else
error("不能保存类型为 " .. type(value) .. " 的值")
end
return output
end
function compareSerializedTable (t1, t2)
if (#t1 ~= #t2) then
return false
end
for i = #t1, 1, -1 do
local line = t1 [i]
for k, comp in ipairs (t2) do
if (line == comp) then
table.remove (t1, i)
table.remove (t2, k)
break
end
end
end
return (#t1 == 0 and #t2 == 0)
end
t1 = {{1,1},{2,2}}
t2 = {{1,1},{2,2}}
t3 = {{1,1},{2,2},{3,3}}
o1 = save ('t', t1)
o2 = save ('t', t2)
o3 = save ('t', t3)
print (compareSerializedTable (o1, o2)) --true
print (compareSerializedTable (o1, o3)) --false
2018-01-19 21:05:57
用户4446971
你需要的是一个表格比较函数。由于有许多不同的实现,因此这不是语言的内置函数。
一个常见的实现是深度比较。下面的函数将深度比较表格,它有第三个参数来忽略元表或不忽略。
function deepcompare(t1, t2, ignore_mt)
local ty1 = type(t1)
local ty2 = type(t2)
if ty1 ~= ty2 then
return false
end
-- 非表格类型可以直接比较
if ty1 ~= "table" and ty2 ~= "table" then
return t1 == t2
end
-- 同样可以比较具有 __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
2020-04-09 09:57:06
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

我的解决方案并非绝对(不使用键),但应该适用于你提出的嵌套表。我的概念是递归和简单的:
从每个输入中取一个条目,确保它们:类型匹配,都是表格,并且两个表格具有相同的长度。如果这三件事都成立,那么现在可以递归地1:1比较这两个表格。如果类型不匹配或表格长度不同,则会自动失败。
function compare (one, two) if type(one) == type(two) then if type(one) == "table" then if #one == #two then -- 如果两种类型相同,都是表格且表格大小相同,则递归遍历每个表格条目。 for loop=1, #one do if compare (one[loop], two[loop]) == false then return false end end -- 所有表内容都匹配 return true end else -- 值不是表格但类型匹配。比较它们并返回它们是否匹配 return one == two end end return false end do t1 = {{1,1},{2,2}} t2 = {{1,1},{2,2}} t3 = {{1,1},{2,2},{3,3}} print (string.format( "t1 == t2 : %s", tostring(compare (t1,t2)))) print (string.format( "t1 == t3 : %s", tostring(compare (t1,t3)))) end输出是:
t1 == t2 : true t1 == t3 : false