我想检查两个表是否在Lua中具有相同的值,但是没有找到方法.
我使用运算符==,它似乎只是检查相同的对象,但不是表中的元素.
如果我有两张桌子,
a={}
b={}
Run Code Online (Sandbox Code Playgroud)
价值a==b是false.
但如果
a={}
b=a
Run Code Online (Sandbox Code Playgroud)
价值a==b是true.
我想知道是否有办法检查Lua中具有相同元素的两个表.是否有内置功能table.equals()可以检查?
没有用于按内容比较表的内置函数.
你必须自己写.您需要决定是要逐个或深入地按内容比较表.有关一些想法,请参阅https://web.archive.org/web/20131225070434/http://snippets.luacode.org/snippets/Deep_Comparison_of_Two_Values_3.
如果你真的想测试简单的表试试这个......
function do_tables_match( a, b )
return table.concat(a) == table.concat(b)
end
Run Code Online (Sandbox Code Playgroud)
另外,与您的具体示例相比的内容如下...
function is_table_empty( table_to_test )
-- Doesn't work
return table_to_test == {}
-- Works only if the table is numeric keyed with no gaps
return #table_to_test = 0
-- Works!
return next( table_to_test ) ~= nil
end
Run Code Online (Sandbox Code Playgroud)
小智 7
我为Rutrus解决方案提供了一些改进.
function equals(o1, o2, ignore_mt)
if o1 == o2 then return true end
local o1Type = type(o1)
local o2Type = type(o2)
if o1Type ~= o2Type then return false end
if o1Type ~= 'table' then return false end
if not ignore_mt then
local mt1 = getmetatable(o1)
if mt1 and mt1.__eq then
--compare using built in method
return o1 == o2
end
end
local keySet = {}
for key1, value1 in pairs(o1) do
local value2 = o2[key1]
if value2 == nil or equals(value1, value2, ignore_mt) == false then
return false
end
keySet[key1] = true
end
for key2, _ in pairs(o2) do
if not keySet[key2] then return false end
end
return true
end
Run Code Online (Sandbox Code Playgroud)
请注意,此解决方案不考虑自引用.你可以使用pequals(下面).当你的代码中有一些技巧时,这很有用.但是不要使用这种方法进行定期检查!它慢了.此外,如果您的对象具有自引用,则应重新分析您的结构.自我引用可能是糟糕架构的标志.
local function internalProtectedEquals(o1, o2, ignore_mt, callList)
if o1 == o2 then return true end
local o1Type = type(o1)
local o2Type = type(o2)
if o1Type ~= o2Type then return false end
if o1Type ~= 'table' then return false end
-- add only when objects are tables, cache results
local oComparisons = callList[o1]
if not oComparisons then
oComparisons = {}
callList[o1] = oComparisons
end
-- false means that comparison is in progress
oComparisons[o2] = false
if not ignore_mt then
local mt1 = getmetatable(o1)
if mt1 and mt1.__eq then
--compare using built in method
return o1 == o2
end
end
local keySet = {}
for key1, value1 in pairs(o1) do
local value2 = o2[key1]
if value2 == nil then return false end
local vComparisons = callList[value1]
if not vComparisons or vComparisons[value2] == nil then
if not internalProtectedEquals(value1, value2, ignore_mt, callList) then
return false
end
end
keySet[key1] = true
end
for key2, _ in pairs(o2) do
if not keySet[key2] then
return false
end
end
-- comparison finished - objects are equal do not compare again
oComparisons[o2] = true
return true
end
function pequals(o1, o2, ignore_mt)
return internalProtectedEquals(o1, o2, ignore_mt, {})
end
Run Code Online (Sandbox Code Playgroud)
您也可以在lua wiki上分析CompareTables.