45,647
edits
(Created page with "--[[ ------------------------------------------------------------------------------------ -- table (formerly TableTools) --...") |
No edit summary |
||
Line 3: | Line 3: | ||
-- table (formerly TableTools) -- | -- table (formerly TableTools) -- | ||
-- -- | -- -- | ||
-- This module | -- This module includes a number of functions for dealing with Lua tables. -- | ||
-- It is a meta-module, meant to be called from other Lua modules, and should -- | -- It is a meta-module, meant to be called from other Lua modules, and should -- | ||
-- not be called directly from #invoke. -- | -- not be called directly from #invoke. -- | ||
Line 144: | Line 144: | ||
return deepcopy(orig, not noMetatable, already_seen) | return deepcopy(orig, not noMetatable, already_seen) | ||
end | |||
--[[ | |||
------------------------------------------------------------------------------------ | |||
-- append | |||
-- | |||
-- This appends two tables together and returns the result. Compare the Lisp | |||
-- expression (append list1 list2). | |||
------------------------------------------------------------------------------------ | |||
--]] | |||
function export.append(t1, t2) | |||
checkType('append', 1, t1, 'table') | |||
checkType('append', 2, t2, 'table') | |||
local ret = {} | |||
for _, v in ipairs(t1) do | |||
table.insert(ret, v) | |||
end | |||
for _, v in ipairs(t2) do | |||
table.insert(ret, v) | |||
end | |||
return ret | |||
end | end | ||
Line 371: | Line 392: | ||
until t[i] == nil | until t[i] == nil | ||
return i - 1 | return i - 1 | ||
end | end | ||
Line 396: | Line 405: | ||
]] | ]] | ||
function export.deepEquals(x, y) | function export.deepEquals(x, y) | ||
if type(x) == "table" and type(y) == "table" then | |||
-- Two tables are the same if they have the same number of elements | |||
-- and all keys that are present in one of the tables compare equal | |||
-- to the corresponding keys in the other table, using structural | |||
-- comparison. | |||
local sizex = 0 | |||
for key, value in pairs(x) do | |||
if not export.deepEquals(value, y[key]) then | |||
return false | |||
end | |||
sizex = sizex + 1 | |||
end | |||
local sizey = export.size(y) | |||
if sizex ~= sizey then | |||
return false | |||
end | |||
return true | |||
end | |||
return x == y | |||
end | end | ||
Line 430: | Line 439: | ||
]] | ]] | ||
function export.deepEqualsList(x, y) | function export.deepEqualsList(x, y) | ||
if type(x) == "table" and type(y) == "table" then | |||
if #x ~= #y then | |||
return false | |||
end | |||
for key, value in ipairs(x) do | |||
if not export.deepEqualsList(value, y[key]) then | |||
return false | |||
end | |||
end | |||
return true | |||
end | |||
return x == y | |||
end | |||
--[[ | |||
Given a list and a value to be found, return true if the value is in the array | |||
portion of the list. Shallow comparison is used unless `deepCompare` is given | |||
(in which case comparison is done using `deepEqualsList`). | |||
]] | |||
function export.contains(list, x, deepCompare) | |||
checkType('contains', 1, list, 'table') | |||
if deepCompare then | |||
for _, v in ipairs(list) do | |||
if export.deepEqualsList(v, x) then return true end | |||
end | |||
else | |||
for _, v in ipairs(list) do | |||
if v == x then return true end | |||
end | |||
end | |||
return false | |||
end | |||
--[[ | |||
Given a general table and a value to be found, return true if the value is in | |||
either the array or hashmap portion of the table. Shallow comparison is used | |||
unless `deepCompare` is given (in which case comparison is done using | |||
`deepEquals`). | |||
]] | |||
function export.tableContains(tbl, x, deepCompare) | |||
checkType('tableContains', 1, tbl, 'table') | |||
if deepCompare then | |||
for _, v in pairs(tbl) do | |||
if export.deepEquals(v, x) then return true end | |||
end | |||
else | |||
for _, v in pairs(tbl) do | |||
if v == x then return true end | |||
end | |||
end | |||
return false | |||
end | |||
--[[ | |||
Given a list and a value to be inserted, append or insert the value if not | |||
already present in the list. Shallow comparison is used unless `deepCompare` | |||
is given (in which case comparison is done using `deepEqualsList`). Appends to | |||
the end, like the default behavior of table.insert(), unless `pos` is given, | |||
in which case insertion happens at position `pos` (i.e. before the existing | |||
item at position `pos`). | |||
NOTE: The order of `item` and `pos` is reversed in comparison to table.insert(), | |||
which uses `table.insert(list, item)` to insert at the end but | |||
`table.insert(list, pos, item)` to insert at position POS. | |||
]] | |||
-- append to list if element not already present | |||
function export.insertIfNot(list, item, pos, deepCompare) | |||
if not export.contains(list, item, deepCompare) then | |||
if pos then | |||
table.insert(list, pos, item) | |||
else | |||
table.insert(list, item) | |||
end | |||
end | |||
end | end | ||