[checked revision] | [checked revision] |
m (Syncing content across wikis) |
m (Syncing content across wikis, if something seems broken as a result let me know) |
||
Line 2: | Line 2: | ||
local p = {} |
local p = {} |
||
+ | |||
+ | function p.generalLength(tbl) |
||
+ | local n = 0 |
||
+ | for _, _ in pairs(tbl) do |
||
+ | n = n + 1 |
||
+ | end |
||
+ | return n |
||
+ | end |
||
+ | |||
+ | function p.getKeysAndSort(tbl, f) |
||
+ | local ret = {} |
||
+ | for k, _ in pairs(tbl) do |
||
⚫ | |||
+ | end |
||
+ | table.sort(ret, f) |
||
+ | return ret |
||
+ | end |
||
function p.keyOf(tbl, val) |
function p.keyOf(tbl, val) |
||
Line 13: | Line 30: | ||
function p.hash(tbl) |
function p.hash(tbl) |
||
⚫ | |||
local hash = {} |
local hash = {} |
||
for k, v in pairs(tbl) do |
for k, v in pairs(tbl) do |
||
Line 50: | Line 68: | ||
end |
end |
||
− | function p.mergeArrays(tbl1, |
+ | function p.mergeArrays(tbl1, ...) |
-- tbl1 is modified to include the elements of tbl2 appended to the end. Order is preserved. |
-- tbl1 is modified to include the elements of tbl2 appended to the end. Order is preserved. |
||
if not tbl1 then tbl1 = {} end |
if not tbl1 then tbl1 = {} end |
||
+ | local newTables = {...} |
||
⚫ | |||
− | for _, |
+ | for _, tbl2 in ipairs(newTables) do |
+ | for _, v in ipairs(tbl2) do |
||
⚫ | |||
⚫ | |||
+ | end |
||
end |
end |
||
return tbl1 |
return tbl1 |
||
end |
end |
||
− | function p.merge(tbl1, |
+ | function p.merge(tbl1, ...) |
-- tbl1 is modified to include all the elements of tbl2. |
-- tbl1 is modified to include all the elements of tbl2. |
||
if not tbl1 then tbl1 = {} end |
if not tbl1 then tbl1 = {} end |
||
+ | local tables = {...} |
||
⚫ | |||
− | for |
+ | for _, tbl2 in ipairs(tables) do |
+ | for k, v in pairs(tbl2) do |
||
⚫ | |||
+ | tbl1[k] = v |
||
+ | end |
||
end |
end |
||
return tbl1 |
return tbl1 |
||
Line 75: | Line 97: | ||
tbl[key] = nil |
tbl[key] = nil |
||
return output |
return output |
||
+ | end |
||
+ | |||
+ | function p.removeValue(tbl, val) |
||
+ | for k, v in pairs(tbl) do |
||
+ | if val == v then |
||
+ | tbl[k] = nil |
||
+ | end |
||
+ | end |
||
+ | return tbl |
||
+ | end |
||
+ | |||
+ | function p.removeValueFromArray(tbl, val) |
||
+ | local len = #tbl |
||
+ | for i = len, 1, -1 do |
||
+ | if tbl[i] == val then |
||
+ | table.remove(i) |
||
+ | end |
||
+ | end |
||
+ | end |
||
+ | |||
+ | function p.removeDuplicates(tbl) |
||
+ | local hash = {} |
||
+ | local ret = {} |
||
+ | for _, v in ipairs(tbl) do |
||
+ | if not hash[v] then |
||
+ | hash[v] = true |
||
+ | ret[#ret+1] = v |
||
+ | end |
||
+ | end |
||
+ | return ret |
||
end |
end |
||
Line 107: | Line 159: | ||
function p.slice(tbl, s, e) |
function p.slice(tbl, s, e) |
||
+ | if s < 0 then |
||
+ | s = #tbl + 1 + s |
||
+ | end |
||
+ | if e < 0 then |
||
+ | e = #tbl + 1 + e |
||
+ | end |
||
local tbl2 = {} |
local tbl2 = {} |
||
for k = s, e do |
for k = s, e do |
||
Line 152: | Line 210: | ||
end |
end |
||
− | function p.mapInPlace(tbl, f, |
+ | function p.mapInPlace(tbl, f, ...) |
for k, v in pairs(tbl) do |
for k, v in pairs(tbl) do |
||
− | tbl[k] = f(v) |
+ | tbl[k] = f(v, ...) |
end |
end |
||
return tbl |
return tbl |
||
end |
end |
||
− | function p. |
+ | function p.mapArrayInPlace(tbl, f, ...) |
+ | for k, v in ipairs(tbl) do |
||
+ | tbl[k] = f(v, ...) |
||
+ | end |
||
+ | return tbl |
||
+ | end |
||
+ | |||
+ | function p.mapArraySafe(tbl, f, ...) |
||
+ | local tbl2 = {} |
||
+ | for k, v in ipairs(tbl) do |
||
+ | tbl2[k] = f(v, ...) |
||
+ | end |
||
+ | return tbl2 |
||
+ | end |
||
+ | |||
+ | function p.mapSafe(tbl, f, ...) |
||
local tbl2 = mw.clone(tbl) |
local tbl2 = mw.clone(tbl) |
||
p.removeFalseEntries(tbl2) |
p.removeFalseEntries(tbl2) |
||
for k, v in ipairs(tbl2) do |
for k, v in ipairs(tbl2) do |
||
− | tbl2[k] = f(v) |
+ | tbl2[k] = f(v, ...) |
end |
end |
||
return tbl2 |
return tbl2 |
||
end |
end |
||
− | function p. |
+ | function p.mapDictInPlace(tbl, f, ...) |
+ | for _, v in ipairs(tbl) do |
||
+ | tbl[v] = f(tbl[v], ...) |
||
+ | end |
||
+ | return tbl |
||
+ | end |
||
+ | |||
+ | function p.mapRowsInPlace(tbl, f, ...) |
||
for k, row in ipairs(tbl) do |
for k, row in ipairs(tbl) do |
||
− | f(row) |
+ | f(row, ...) |
+ | row.index = k |
||
end |
end |
||
return tbl |
return tbl |
||
end |
end |
||
− | function p.mapDictRowsInPlace(tbl, f) |
+ | function p.mapDictRowsInPlace(tbl, f, ...) |
for _, v in ipairs(tbl) do |
for _, v in ipairs(tbl) do |
||
− | f(tbl[v]) |
+ | f(tbl[v], ...) |
end |
end |
||
return tbl |
return tbl |
||
Line 184: | Line 265: | ||
function p.concat(tbl, sep, f, max) |
function p.concat(tbl, sep, f, max) |
||
-- f is a function that doesn't take any additional args |
-- f is a function that doesn't take any additional args |
||
+ | if not tbl then return end |
||
⚫ | |||
if f then |
if f then |
||
− | p. |
+ | return table.concat(p.mapArraySafe(tbl, f), sep) |
else |
else |
||
p.removeFalseEntries(tbl, max) |
p.removeFalseEntries(tbl, max) |
||
Line 191: | Line 274: | ||
return table.concat(tbl, sep) |
return table.concat(tbl, sep) |
||
end |
end |
||
+ | |||
+ | -- function p.concatSafe(tbl, sep, f, ...) |
||
+ | -- if not sep then sep = ',' end |
||
+ | -- if f then |
||
+ | -- local tbl2 = p.mapArraySafe(tbl, f, ...) |
||
+ | -- else |
||
+ | -- p.removeFalseEntries(tbl, max) |
||
+ | -- end |
||
+ | -- return table.concat(tbl, sep) |
||
+ | -- end |
||
function p.concatSafe(tbl, sep, f) |
function p.concatSafe(tbl, sep, f) |
||
Line 238: | Line 331: | ||
end |
end |
||
return tbl |
return tbl |
||
+ | end |
||
+ | |||
+ | function p.guaranteeTable(c, f, ...) |
||
+ | if not c then return nil end |
||
+ | if type(c) == 'table' then |
||
+ | return f and f(c, ...) or c |
||
+ | end |
||
+ | return { f and f(c, ...) or c } |
||
+ | end |
||
+ | |||
+ | function p.guaranteeIndex(tbl, i) |
||
+ | if type(i) == 'number' then return i end |
||
+ | return p.keyOf(tbl, i) |
||
+ | end |
||
+ | |||
+ | function p.concatIfTable(tbl, sep) |
||
+ | if not tbl then return nil end |
||
+ | return p.concat(p.guaranteeTable(tbl), sep) |
||
+ | end |
||
+ | |||
+ | function p.nextNonFalse(tbl) |
||
+ | for _, v in pairs(tbl) do |
||
+ | if v then return v end |
||
+ | end |
||
+ | end |
||
+ | |||
+ | function p.interlace(tbl) |
||
+ | local ret = {} |
||
+ | local _, keyList = next(tbl) |
||
+ | for key, _ in pairs(keyList) do |
||
+ | ret[key] = {} |
||
+ | end |
||
+ | for k, v in pairs(tbl) do |
||
+ | for key, _ in pairs(keyList) do |
||
+ | ret[key][k] = v[key] |
||
+ | end |
||
+ | end |
||
+ | return ret |
||
+ | end |
||
+ | |||
+ | function p.initTable(tbl, key) |
||
+ | if tbl[key] then return end |
||
+ | tbl[key] = {} |
||
+ | end |
||
+ | |||
+ | function p.initDict(tbl, key) |
||
+ | if tbl[key] then return end |
||
+ | tbl[key] = {} |
||
+ | tbl[#tbl+1] = key |
||
end |
end |
||
Revision as of 12:03, 15 July 2019
To edit the documentation or categories for this module, click here.
local lang = mw.getLanguage('en')
local p = {}
function p.generalLength(tbl)
local n = 0
for _, _ in pairs(tbl) do
n = n + 1
end
return n
end
function p.getKeysAndSort(tbl, f)
local ret = {}
for k, _ in pairs(tbl) do
ret[#ret+1] = k
end
table.sort(ret, f)
return ret
end
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.hash(tbl)
if not tbl then return {} end
local hash = {}
for k, v in pairs(tbl) do
hash[v] = k
end
return hash
end
function p.appendHash(parent, tbl)
for k, v in pairs(tbl) do
parent[v] = k
end
return parent
end
-- sorts tblToSort to be in the same order as the elements appear in lookup
function p.sortByKeyOrder(tblToSort,values)
local lookup = p.hash(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, ...)
-- tbl1 is modified to include the elements of tbl2 appended to the end. Order is preserved.
if not tbl1 then tbl1 = {} end
local newTables = {...}
for _, tbl2 in ipairs(newTables) do
for _, v in ipairs(tbl2) do
tbl1[#tbl1+1] = v
end
end
return tbl1
end
function p.merge(tbl1, ...)
-- tbl1 is modified to include all the elements of tbl2.
if not tbl1 then tbl1 = {} end
local tables = {...}
for _, tbl2 in ipairs(tables) do
for k, v in pairs(tbl2) do
tbl1[k] = v
end
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
function p.removeValue(tbl, val)
for k, v in pairs(tbl) do
if val == v then
tbl[k] = nil
end
end
return tbl
end
function p.removeValueFromArray(tbl, val)
local len = #tbl
for i = len, 1, -1 do
if tbl[i] == val then
table.remove(i)
end
end
end
function p.removeDuplicates(tbl)
local hash = {}
local ret = {}
for _, v in ipairs(tbl) do
if not hash[v] then
hash[v] = true
ret[#ret+1] = v
end
end
return ret
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)
if s < 0 then
s = #tbl + 1 + s
end
if e < 0 then
e = #tbl + 1 + e
end
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, ...)
for k, v in pairs(tbl) do
tbl[k] = f(v, ...)
end
return tbl
end
function p.mapArrayInPlace(tbl, f, ...)
for k, v in ipairs(tbl) do
tbl[k] = f(v, ...)
end
return tbl
end
function p.mapArraySafe(tbl, f, ...)
local tbl2 = {}
for k, v in ipairs(tbl) do
tbl2[k] = f(v, ...)
end
return tbl2
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.mapDictInPlace(tbl, f, ...)
for _, v in ipairs(tbl) do
tbl[v] = f(tbl[v], ...)
end
return tbl
end
function p.mapRowsInPlace(tbl, f, ...)
for k, row in ipairs(tbl) do
f(row, ...)
row.index = k
end
return tbl
end
function p.mapDictRowsInPlace(tbl, f, ...)
for _, v in ipairs(tbl) do
f(tbl[v], ...)
end
return tbl
end
function p.concat(tbl, sep, f, max)
-- f is a function that doesn't take any additional args
if not tbl then return end
if not sep then sep = ',' end
if f then
return table.concat(p.mapArraySafe(tbl, f), sep)
else
p.removeFalseEntries(tbl, max)
end
return table.concat(tbl, sep)
end
-- function p.concatSafe(tbl, sep, f, ...)
-- if not sep then sep = ',' end
-- if f then
-- local tbl2 = p.mapArraySafe(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
function p.alphabetize(tbl)
local hash = {}
local nocase = {}
for i, v in ipairs(tbl) do
nocase[i] = lang:caseFold(v)
hash[nocase[i]] = v
end
table.sort(nocase)
for i, v in ipairs(nocase) do
tbl[i] = hash[v]
end
return tbl
end
function p.guaranteeTable(c, f, ...)
if not c then return nil end
if type(c) == 'table' then
return f and f(c, ...) or c
end
return { f and f(c, ...) or c }
end
function p.guaranteeIndex(tbl, i)
if type(i) == 'number' then return i end
return p.keyOf(tbl, i)
end
function p.concatIfTable(tbl, sep)
if not tbl then return nil end
return p.concat(p.guaranteeTable(tbl), sep)
end
function p.nextNonFalse(tbl)
for _, v in pairs(tbl) do
if v then return v end
end
end
function p.interlace(tbl)
local ret = {}
local _, keyList = next(tbl)
for key, _ in pairs(keyList) do
ret[key] = {}
end
for k, v in pairs(tbl) do
for key, _ in pairs(keyList) do
ret[key][k] = v[key]
end
end
return ret
end
function p.initTable(tbl, key)
if tbl[key] then return end
tbl[key] = {}
end
function p.initDict(tbl, key)
if tbl[key] then return end
tbl[key] = {}
tbl[#tbl+1] = key
end
return p