Clients/Client2018/content/LuaPackages/AppTempCommon/LuaApp/TableUtilities.lua

174 lines
3.4 KiB
Lua

--[[
Provides functions for comparing and printing lua tables.
]]
local TableUtilities = {}
local defaultIgnore = {}
--[[
Takes two tables A and B, returns if they have the same key-value pairs
Except ignored keys
]]
function TableUtilities.ShallowEqual(A, B, ignore)
if not A or not B then
return false
elseif A == B then
return true
end
if not ignore then
ignore = defaultIgnore
end
for key, value in pairs(A) do
if B[key] ~= value and not ignore[key] then
return false
end
end
for key, value in pairs(B) do
if A[key] ~= value and not ignore[key] then
return false
end
end
return true
end
--[[
Takes two tables A, B and a key, returns if two tables have the same value at key
]]
function TableUtilities.EqualKey(A, B, key)
if A and B and key and key ~= "" and A[key] and B[key] and A[key] == B[key] then
return true
end
return false
end
--[[
Takes two tables A and B, returns a new table with elements of A
which are either not keys in B or have a different value in B
]]
function TableUtilities.TableDifference(A, B)
local new = {}
for key, value in pairs(A) do
if B[key] ~= A[key] then
new[key] = value
end
end
return new
end
--[[
Takes a list and returns a table whose
keys are elements of the list and whose
values are all true
]]
local function membershipTable(list)
local result = {}
for i = 1, #list do
result[list[i]] = true
end
return result
end
--[[
Takes a table and returns a list of keys in that table
]]
local function listOfKeys(t)
local result = {}
for key,_ in pairs(t) do
table.insert(result, key)
end
return result
end
--[[
Takes two lists A and B, returns a new list of elements of A
which are not in B
]]
function TableUtilities.ListDifference(A, B)
return listOfKeys(TableUtilities.TableDifference(membershipTable(A), membershipTable(B)))
end
--[[
For debugging. Returns false if the given table has any of the following:
- a key that is neither a number or a string
- a mix of number and string keys
- number keys which are not exactly 1..#t
]]
function TableUtilities.CheckListConsistency(t)
local containsNumberKey = false
local containsStringKey = false
local numberConsistency = true
local index = 1
for x, _ in pairs(t) do
if type(x) == 'string' then
containsStringKey = true
elseif type(x) == 'number' then
if index ~= x then
numberConsistency = false
end
containsNumberKey = true
else
return false
end
if containsStringKey and containsNumberKey then
return false
end
index = index + 1
end
if containsNumberKey then
return numberConsistency
end
return true
end
--[[
For debugging, serializes the given table to a reasonable string that might even interpret as lua.
]]
function TableUtilities.RecursiveToString(t, indent)
indent = indent or ''
if type(t) == 'table' then
local result = ""
if not TableUtilities.CheckListConsistency(t) then
result = result .. "-- WARNING: this table fails the list consistency test\n"
end
result = result .. "{\n"
for k,v in pairs(t) do
if type(k) == 'string' then
result = result
.. " "
.. indent
.. tostring(k)
.. " = "
.. TableUtilities.RecursiveToString(v, " "..indent)
..";\n"
end
if type(k) == 'number' then
result = result .. " " .. indent .. TableUtilities.RecursiveToString(v, " "..indent)..",\n"
end
end
result = result .. indent .. "}"
return result
else
return tostring(t)
end
end
return TableUtilities