Last active
January 11, 2016 00:27
-
-
Save meepen/910c9b7b2bdaf0fe5a32 to your computer and use it in GitHub Desktop.
table.StructuralEquals
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local TableEqualsIntrnl | |
local NaN = {}; | |
local function NaNSafe(n) return n ~= n and NaN or n; end | |
local EqualOps = { | |
["function"] = function(f1, f2) | |
local s, dump = pcall(string.dump, f1) | |
local s2, dump2 = pcall(string.dump, f2) | |
-- test for lua function bytecode first, then c function | |
return s and s2 and dump == dump2 or f1 == f2 | |
end, | |
table = function(t1, t2, cache) | |
return TableEqualsIntrnl(t1, t2, cache) | |
end | |
} | |
function TableEqualsIntrnl(t1, t2, cache) | |
cache[t2] = cache[t2] or {} | |
if (cache[t2][t1]) then return true end | |
cache[t2][t1] = {} | |
for k,v in next, t1, nil do | |
local isnew = false | |
if (not cache[t2][t1][k]) then | |
cache[t2][t1][k] = true | |
isnew = true | |
local ktype = type(k) | |
if (ktype ~= "number" and ktype ~= "string" and ktype ~= "boolean") then | |
for k2 in next, t2, nil do | |
if (type(k2) == ktype and EqualOps[ktype](k, k2, cache)) then | |
k = k2 | |
break | |
end | |
end | |
end | |
end | |
if (isnew or not cache[t2][t1][k]) then | |
cache[t2][t1][k] = true | |
local v2 = t2[k] | |
if (type(v) == "table" and type(v2) == "table") then | |
if (not TableEqualsIntrnl(v, v2, cache)) then | |
return false | |
end | |
elseif (type(v) == "function" and type(v2) == "function") then | |
if(string.dump(v) ~= string.dump(v2)) then | |
return false | |
end | |
elseif (NaNSafe(v) ~= NaNSafe(v2)) then | |
return false | |
end | |
end | |
end | |
for k,v in next, t2, nil do | |
if (not cache[t2][t1][k]) then | |
return false | |
end | |
end | |
return true | |
end | |
function table.StructuralEquals(t1, t2) return TableEqualsIntrnl(t1, t2, {}) end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment