Module:table: Difference between revisions
Jump to navigation
Jump to search
getNested() moved to Module:table/getNested and setNested() moved to Module:table/setNested.
No edit summary |
(getNested() moved to Module:table/getNested and setNested() moved to Module:table/setNested.) |
||
| Line 1: | Line 1: | ||
local export = {} | |||
--[==[ intro: | |||
This module provides functions for dealing with Lua tables. All of them, except for two helper functions, take a table | |||
as their first argument. | |||
Some functions are available as methods in the arrays created by [[Module:array]]. | |||
Functions by what they do: | |||
* Create a new table: | |||
** `shallowCopy`, `deepCopy`, `removeDuplicates`, `numKeys`, `compressSparseArray`, `keysToList`, `reverse`, `invert`, `listToSet` | |||
* Create an array: | |||
** `removeDuplicates`, `numKeys`, `compressSparseArray`, `keysToList`, `reverse` | |||
* Return information about the table: | |||
** `size`, `length`, `contains`, `isArray`, `deepEquals` | |||
* Treat the table as an array (that is, operate on the values in the array portion of the table: values indexed by | |||
consecutive integers starting at {1}): | |||
** `removeDuplicates`, `length`, `contains`, `serialCommaJoin`, `reverseIpairs`, `reverse`, `invert`, `listToSet`, `isArray` | |||
* Treat a table as a sparse array (that is, operate on values indexed by non-consecutive integers): | |||
** `numKeys`, `maxIndex`, `compressSparseArray`, `sparseConcat`, `sparseIpairs` | |||
* Generate an iterator: | |||
** `sparseIpairs`, `sortedPairs`, `reverseIpairs` | |||
* Other functions: | |||
** `sparseConcat`, `serialCommaJoin`, `reverseConcat` | |||
The original version was a copy of {{w|Module:TableTools}} on Wikipedia via [[c:Module:TableTools|Module:TableTools]] on | |||
Commons, but in the course of time this module has been almost completely rewritten, with many new functions added. The | |||
main legacy of this is the use of camelCase for function names rather than snake_case, as is normal in the English | |||
Wiktionary. | |||
]==] | |||
local | local load_module = "Module:load" | ||
local math_module = "Module:math" | local math_module = "Module:math" | ||
| Line 19: | Line 36: | ||
local concat = table.concat | local concat = table.concat | ||
local | local dump = mw.dumpObject | ||
local ipairs = ipairs | local ipairs = ipairs | ||
local ipairs_default_iter = ipairs{export} | local ipairs_default_iter = ipairs{export} | ||
local next = next | local next = next | ||
local pairs = pairs | local pairs = pairs | ||
local require = require | local require = require | ||
local select = select | local select = select | ||
local signed_index -- defined as export.signedIndex | local signed_index -- defined as export.signedIndex | ||
local table_len -- defined as export.length | local table_len -- defined as export.length | ||
local type = type | local type = type | ||
--[==[ | --[==[ | ||
Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no overhead after the first call, since the target functions are called directly in any subsequent calls.]==] | Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no overhead after the first call, since the target functions are called directly in any subsequent calls.]==] | ||
local function is_integer(...) | |||
is_integer = require(math_module).is_integer | |||
return is_integer(...) | |||
end | end | ||
local function safe_require(...) | |||
safe_require = require(load_module).safe_require | |||
return safe_require(...) | |||
end | end | ||
| Line 175: | Line 68: | ||
end | end | ||
signed_index = export.signedIndex | signed_index = export.signedIndex | ||
--[==[ | --[==[ | ||
| Line 315: | Line 74: | ||
return next, t, nil | return next, t, nil | ||
end | end | ||
--[==[ | --[==[ | ||
| Line 321: | Line 79: | ||
function export.rawIpairs(t) | function export.rawIpairs(t) | ||
return ipairs_default_iter, t, 0 | return ipairs_default_iter, t, 0 | ||
end | end | ||
| Line 469: | Line 99: | ||
end | end | ||
table_len = export.length | table_len = export.length | ||
local function getIteratorValues(i, j , step, t_len) | local function getIteratorValues(i, j , step, t_len) | ||
| Line 915: | Line 165: | ||
return t_new | return t_new | ||
end | end | ||
--[==[ | --[==[ | ||
Given an array `list` and function `func`, iterate through the array applying {func(k, v)} (where `k` is an index, and | Given an array `list` and function `func`, iterate through the array applying {func(k, v)} (where `k` is an index, and | ||
| Line 935: | Line 185: | ||
# j=-3, step=-1 results in backward iteration from the end to the 3rd last index.]==] | # j=-3, step=-1 results in backward iteration from the end to the 3rd last index.]==] | ||
function export.apply(t, func, i, j, step) | function export.apply(t, func, i, j, step) | ||
return replace(t, func, i, j, step) | return replace(t, func, i, j, step, false) | ||
end | end | ||
| Line 1,022: | Line 272: | ||
* `conj`: Conjunction to use; defaults to {"and"}. | * `conj`: Conjunction to use; defaults to {"and"}. | ||
* `punc`: Punctuation to use; default to {","}. | * `punc`: Punctuation to use; default to {","}. | ||
* `dontTag`: Don't tag the serial comma and serial {"and"}. For error messages, in which HTML cannot be used.]==] | * `dontTag`: Don't tag the serial comma and serial {"and"}. For error messages, in which HTML cannot be used. | ||
* `dump`: Each item will be serialized with {mw.dumpObject}. For warnings and error messages.]==] | |||
function export.serialCommaJoin(seq, options) | function export.serialCommaJoin(seq, options) | ||
local length = table_len(seq) | -- If the `dump` option is set, determine the table length as part of the | ||
-- dump loop, instead of calling `table_len` separately. | |||
local length | |||
if options and options.dump then | |||
local i, item = 1, seq[1] | |||
if item ~= nil then | |||
local dumped = {} | |||
repeat | |||
dumped[i] = dump(item) | |||
i = i + 1 | |||
item = seq[i] | |||
until item == nil | |||
seq = dumped | |||
end | |||
length = i - 1 | |||
else | |||
length = table_len(seq) | |||
end | |||
if length == 0 then | if length == 0 then | ||
return "" | return "" | ||
elseif length == 1 then | elseif length == 1 then | ||
return seq[1] | return seq[1] | ||
end | end | ||
local conj | local conj = options and options.conj | ||
if conj == nil then | |||
conj = "and" | |||
end | |||
if length == 2 then | |||
return seq[1] .. " " .. conj .. " " .. seq[2] | |||
end | |||
local punc, dont_tag | |||
if options then | if options then | ||
punc = options.punc | |||
punc = | if punc == nil then | ||
punc = "," | |||
end | |||
dont_tag = options.dontTag | dont_tag = options.dontTag | ||
else | else | ||
punc = "," | |||
end | end | ||
local comma | local comma | ||
if dont_tag then | if dont_tag then | ||
comma = | comma = "" -- since by default the serial comma doesn't display, when we can't tag we shouldn't display it. | ||
conj = " " .. conj .. " " | conj = " " .. conj .. " " | ||
else | else | ||
| Line 1,050: | Line 328: | ||
conj = "<span class=\"serial-and\"> " .. conj .. "</span> " | conj = "<span class=\"serial-and\"> " .. conj .. "</span> " | ||
end | end | ||
return concat(seq, punc .. " ", 1, length - 1) .. comma .. conj .. seq[length] | return concat(seq, punc .. " ", 1, length - 1) .. comma .. conj .. seq[length] | ||
end | end | ||
| Line 1,066: | Line 344: | ||
list[k] = v | list[k] = v | ||
end | end | ||
end | end | ||
| Line 1,221: | Line 354: | ||
end | end | ||
return export | local mt = {} | ||
function mt:__index(k) | |||
local submodule = safe_require("Module:table/" .. k) | |||
self[k] = submodule | |||
return submodule | |||
end | |||
return setmetatable(export, mt) | |||