Module:TableUtil
Jump to navigation
Jump to search
This module has no documentation. If you know how to use this template, please add some.
This module depends on: |
The above documentation is transcluded from Module:TableUtil/doc. (edit | history)
local checkType = require("libraryUtil").checkType;
local util_text = require('Module:TextUtil')
local floor = math.floor
local infinity = math.huge
local p = {}
function p.keyOf(tbl, val)
for k, v in pairs(tbl) do
if v == val then
return k
end
end
return nil
end
function p.lookup(tbl)
local lookup = {}
for k, v in pairs(tbl) do
lookup[v] = k
end
return lookup
end
function p.appendLookup(tbl, parent)
for k, v in pairs(tbl) do
parent[v] = k
end
return
end
-- sorts tblToSort to be in the same order as the elements appear in lookup
function p.sortByKeyOrder(tblToSort,values)
local lookup = p.lookup(values)
table.sort(tblToSort, function (a,b)
return (lookup[a] or 0) < (lookup[b] or 0)
end
)
return
end
function p.sortUnique(tbl)
table.sort(tbl)
local tbl2 = {}
local i = 0
for k, v in ipairs(tbl) do
if v ~= tbl2[i] then
i = i + 1
tbl2[i] = v
end
end
return tbl2
end
function p.mergeArrays(tbl1,tbl2)
-- tbl1 is modified to include the elements of tbl2 appended to the end. Order is preserved.
if not tbl1 then tbl1 = {} end
if not tbl2 then tbl2 = {} end
for _, v in ipairs(tbl2) do
tbl1[#tbl1+1] = v
end
return tbl1
end
function p.merge(tbl1, tbl2)
-- tbl1 is modified to include all the elements of tbl2.
if not tbl1 then tbl1 = {} end
if not tbl2 then tbl2 = {} end
for k, v in pairs(tbl2) do
tbl1[k] = v
end
return tbl1
end
-- table.remove for non-integer key
function p.remove(tbl, key)
local output = tbl[key]
tbl[key] = nil
return output
end
-- returns a copy of tbl with the elements in opposite order (not a deep copy)
function p.reverse(tbl)
local tbl2 = {}
local len = #tbl
for i = len, 1, -1 do
tbl2[len - i + 1] = tbl[i]
end
return tbl2
end
function p.reverseInPlace(tbl)
local len = #tbl
local stop_at = len / 2
for i = 1, stop_at do
local temp = tbl[i]
tbl[i] = tbl[len - i + 1]
tbl[len - i + 1] = temp
end
end
function p.shallowClone(tbl)
-- mostly to be able to use # operator on something from mw.loadData
local tbl2 = {}
for k, v in pairs(tbl) do
tbl2[k] = v
end
return tbl2
end
function p.slice(tbl, s, e)
local tbl2 = {}
for k = s, e do
tbl2[#tbl2+1] = tbl[k]
end
return tbl2
end
-- prints the table as a comma-separated list with and
function p.printList(tbl)
if #tbl == 1 then
return tbl[1]
elseif #tbl == 2 then
return table.concat(tbl, ' and ')
else
last = table.remove(tbl, #tbl)
list = table.concat(tbl, ', ')
return list .. ', and ' .. (last or '')
end
end
function p.removeFalseEntries(tbl, max)
if not max then max = #tbl end
local j = 0
for i = 1, max do
if tbl[i] then
j = j + 1
tbl[j] = tbl[i]
end
end
for i = j+1, max do
tbl[i] = nil
end
return tbl
end
function p.padFalseEntries(tbl, max, default)
default = default or ''
for i = 1, max do
if not tbl[i] then
tbl[i] = default
end
end
return tbl
end
function p.mapInPlace(tbl, f, max)
for k, v in pairs(tbl) do
tbl[k] = f(v)
end
return tbl
end
function p.mapSafe(tbl, f)
local tbl2 = mw.clone(tbl)
p.removeFalseEntries(tbl2)
for k, v in ipairs(tbl2) do
tbl2[k] = f(v)
end
return tbl2
end
function p.mapRowsInPlace(tbl, f)
for k, row in ipairs(tbl) do
f(row)
end
return tbl
end
function p.mapDictRowsInPlace(tbl, f)
for _, v in ipairs(tbl) do
f(tbl[v])
end
return tbl
end
function p.splitAndMap(str, f, sep)
sep = '%s*' .. (sep or ',') .. '%s*'
return p.mapInPlace(util_text.split(str, sep), f)
end
function p.concat(tbl, sep, f, max)
-- f is a function that doesn't take any additional args
if f then
p.mapInPlace(tbl, f)
else
p.removeFalseEntries(tbl, max)
end
return table.concat(tbl, sep)
end
function p.concatSafe(tbl, sep, f)
-- f is a function that doesn't take any additional args
local tbl2 = mw.clone(tbl)
if f then
p.mapInPlace(tbl2, f)
else
p.removeFalseEntries(tbl2)
end
return table.concat(tbl2, sep)
end
function p.concatFromArgs(args, argname, sep, f)
-- if fields are saved in args as field1, field2, field3, etc
local i = 1
local tbl = {}
if args[argname] then
tbl[1] = args[argname]
i = 2
end
while args[argname .. i] do
tbl[i] = args[argname .. i]
i = i + 1
end
return next(tbl) and p.concat(tbl, sep, f)
end
function p.crop(tbl, max)
for k, _ in ipairs(tbl) do
if k > max then
tbl[k] = nil
end
end
end
--[[
------------------------------------------------------------------------------------
-- isPositiveInteger
--
-- This function returns true if the given value is a positive integer, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a given table key is in the array part or the
-- hash part of a table.
------------------------------------------------------------------------------------
--]]
function p.isPositiveInteger(v)
if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then
return true
else
return false
end
end
--[[
--------------------------------------------------------------------------------
-- numKeys
--
-- This takes a table and returns an array containing the numbers of any
-- numerical keys that have non-nil values, sorted in numerical order.
--------------------------------------------------------------------------------
--]]
function p.numKeys(t)
checkType('numKeys', 1, t, 'table')
local isPositiveInteger = p.isPositiveInteger
local nums = {}
for k, v in pairs(t) do
if isPositiveInteger(k) then
nums[#nums + 1] = k
end
end
table.sort(nums)
return nums
end
--[[
--------------------------------------------------------------------------------
-- compressSparseArray
--
-- This takes an array with one or more nil values, and removes the nil values
-- while preserving the order, so that the array can be safely traversed with
-- ipairs.
--------------------------------------------------------------------------------
--]]
function p.compressSparseArray(t)
checkType('compressSparseArray', 1, t, 'table')
local ret = {}
local nums = p.numKeys(t)
for _, num in ipairs(nums) do
ret[#ret + 1] = t[num]
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- sparseIpairs
--
-- This is an iterator for sparse arrays. It can be used like ipairs, but can
-- handle nil values.
------------------------------------------------------------------------------------
--]]
function p.sparseIpairs(t)
checkType('sparseIpairs', 1, t, 'table')
local nums = p.numKeys(t)
local i = 0
local lim = #nums
return function ()
i = i + 1
if i <= lim then
local key = nums[i]
return key, t[key]
else
return nil, nil
end
end
end
return p