Documentation Module:Util/doc
This is a meta module.
This module is meant to be used only by other modules. It should not be invoked in wikitext.
Overview
Provides utility functions for programming modules.
Structure
| Group | Function | Description |
|---|---|---|
| string | trim | Trim whitespaces and tabs from a string. |
| trimend | Trim whitespaces and tabs from the end of a string. | |
| split | Splits a string into a table. | |
| table | deepcopy | Copy table and all subtables. (Deep-copy) |
| merge | Recursively merges and/or deep-copies tables. |
Usage
This module should be loaded with require().
local util = {
string = {},
table = {},
}
-- ----------------------------------------------------------------------------
-- util.string
-- ----------------------------------------------------------------------------
--- Trim whitespaces and tabs from a string.
-- @param #string 'str': String to trim.
-- @return #string: Trimmed string.
function util.string.trim(str)
local l = 1
while string.sub(str, l, l) == ' ' or string.sub(str, l, l) == '\t' do
l = l + 1
end
local r = string.len(str)
while string.sub(str, r, r) == ' ' or string.sub(str, r, r) == '\t' do
r = r - 1
end
return string.sub(str, l, r)
end
--- Trim whitespaces and tabs from the end of a string.
-- @param #string 'str': String to trim.
-- @return #string: Trimmed string.
function util.string.trimend(str)
local r = string.len(str)
while string.sub(str, r, r) == ' ' or string.sub(str, r, r) == '\t' do
r = r - 1
end
return string.sub(str, 1, r)
end
--- Splits a string into a table.
--- This does essentially the same thing as mw.text.split, but with significantly better performance.
-- @param #string 'str': String to split.
-- @param #string 'pattern': Pattern to use for splitting. Default is '%s'.
-- @param #bool 'plain': If true, pattern is interpreted as a literal string. Optional.
-- @return #table: Table of strings.
function util.string.split(str, pattern, plain)
if str then
pattern = pattern or "%s"
local out = {}
local init = 1
local split_start, split_end = string.find(str, pattern, init, plain)
while split_start do
out[#out+1] = string.sub(str, init, split_start-1)
init = split_end+1
split_start, split_end = string.find(str, pattern, init, plain)
end
out[#out+1] = string.sub(str, init)
return out
end
return nil
end
-- ----------------------------------------------------------------------------
-- util.table
-- ----------------------------------------------------------------------------
--- Copy table and all subtables. (Deep-copy)
-- @param 'object': Object to copy.
-- @return New table if 'object' is a table, otherwise returns 'object'.
function util.table.deepcopy(object)
local lookup_table = {}
local function _copy(object)
if type(object) ~= "table" then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local new_table = {}
lookup_table[object] = new_table
for i, v in pairs(object) do
new_table[_copy(i)] = _copy(v)
end
return setmetatable(new_table, getmetatable(object))
end
return _copy(object)
end
--- Recursively merges and/or deep-copies tables.
-- Entries in later tables override entries in earlier ones, unless both entries are themselves tables, in which case they are recursively merged.
-- Non-merged tables are deep-copied, so that the result is brand new.
-- @param #table 'tables': Tables to merge.
-- @return #table: Merged tables.
function util.table.merge(tables)
local ret = {}
for _, tbl in ipairs(tables) do
for k, v in pairs(tbl) do
if (type(v) == "table") then
if (type(ret[k] or false) == "table") then
ret[k] = util.table.merge{ret[k], v}
else
ret[k] = util.table.deepcopy(v)
end
else
ret[k] = v
end
end
end
return ret
end
return util