Module:Enum
Module documentation
This documentation is transcluded from Module:Enum/doc. [edit] [purge]
Module:Enum requires Module:LibraryUtil.
Module:Enum requires Module:Logger.
Module:Enum is required by Module:DependencyList.
This module is a helper module to be used by other modules; it may not designed to be invoked directly. See GSWiki:Lua/Helper modules for a full list and more information. For a full list of modules using this helper click here
Module | Function | Type | Use | Example |
---|---|---|---|---|
Enum | all( enum, [fn], [clone|false] ) | table, function/nil, boolean/nil | Loops over the array part of enum and passes each element as the first argument to fn . If fn returns true for all elements then all() returns true , otherwise false . If no function is given function( item ) return item end is used. | |
any( enum, [fn], [clone|false] ) | table, function/nil, boolean/nil | Loops over the array part of enum and passes each element as the first argument to fn . If fn returns true for at least one element then any() returns true , otherwise false . If no function is given function( item ) return item end is used. If clone is true the input enum is deep copied using mw.clone() before use. | ||
contains( enum, elem, [clone|false] ) | table, any, boolean/nil | Returns true if enum contains elem , otherwise returns false. | ||
each( enum, fn, [clone|false] ) | table, function, boolean/nil | Loops over the array part of enum and passes each element as the first argument to fn . This function returns nothing. | ||
filter( enum, [fn], [clone|false] ) | table, function/nil, boolean/nil | Loops over the array part of enum and passes each element as the first argument to fn . If fn returns true the corresponding element is copied to a new table which is then returned. If no function is given function( item ) return item end is used. | ||
find( enum, fn, [default|nil], [clone|false] ) | table, function, any, boolean/nil | Loops over the array part of enum and passes each element as the first argument to fn . The first element where fn returns true is returned. If no elements passes the test, default is returned. | ||
find_index( enum, fn, [default|nil], [clone|false] ) | table, function, any, boolean/nil | Loops over the array part of enum and passes each element as the first argument to fn . The index of the first element where fn returns true is returned. If no elements passes the test, default is returned. | ||
insert( enum1, enum2, [index|#enum1+1], [clone|false] ) | table, table, number, boolean/nil | Returns a new table with enum2 inserted into enum1 at index index . If no index is given, enum2 is appended to enum1 . | ||
intersect( enum1, enum2, [clone|false] ) | table, table, boolean/nil | Returns a table containing elements which exist in both enums. The order of the elements is the same as the order they occure in enum1 . | ||
intersects( enum1, enum2, [clone|false] ) | table, table, boolean/nil | Returns true if both sets have at least one element with equal values. | ||
map( enum, fn, [clone|false] ) | table, function, boolean/nil | Loops over the array part of enum and passes each element as the first argument to fn . The return value of fn is appended to a new table. This new table is returned. | ||
max_by( enum, fn, [clone|false] ) | table, function, boolean/nil | Loops over the array part of enum and passes each element as the first argument to fn . max_by() returns two values, the first is the element where fn returned the largest value, the second is this largest value. The > operator is used for the comparisons. | ||
new( [enum|{}] ) | table | Adds a metatable to enum which allows it use elementwise math operations on the table. Also makes it possible to use the colon : operator with all the other functions listed here that take a table as their first argument.
local t = enum.new{1, 2, 3}
local t2 = enum{4, 5, 6} -- Alternative notation
mw.log( -t ) --> { -1, -2, -3 }
mw.log( t + 2 ) --> { 3, 4, 5 }
mw.log( t - 2 ) --> { -1, 0, 1 }
mw.log( t * 2 ) --> { 2, 4, 6 }
mw.log( t / 2 ) --> { 0.5, 1, 1.5 }
mw.log( t ^ 2 ) --> { 1, 4, 9 }
mw.log( t + t2 ) --> { 5, 7, 9 }
mw.log( t .. t2 ) --> { 1, 2, 3, 4, 5, 6 }
mw.log( t:sum() ) --> 6
mw.log( (t .. t2):reject{3, 4, 5} ) --> { 1, 2, 6 } | ||
newIncrementor( [start|1], [step|1] ) | number, number | Returns a new incrementor function. Every time this incrementor function is called it returns a number step higher than the previous call. The current value can be obtained with inc.n or set inc.n = number where inc is an incrementor function. The step size can be changed with inc.step = number . | ||
range( stop ) range( start, stop, [step|1] ) | number, number, number | Returns a table containing a sequence of numbers from start to stop (both inclusive if ints, end-exclusive if floats) by step . range(4) produces {1, 2, 3, 4} (start defaults to 1 ). range(0, 4) produces {0, 1, 2, 3, 4} . When step is given, it specifies the increment (or decrement). | ||
reduce( enum, fn, [accumulator|enum[1]], [clone|false] ) | table, function, any, boolean/nil | Loops over the array part of enum and passes each element as the first argument and accumulator as the second to fn . The return value of fn becomes the new accumulator . The final value of accumulator is returned. If no accumulator is given then the first element in enum is used. | ||
reject( enum, [fn], [clone|false] ) reject( enum, [table], [clone|false] ) | table, function/table, boolean/nil | The opposite of filter() . If the second argument is a table, every element in enum equal to any of the values in this table will be rejected. | ||
rep( val, n, [clone|false] ) | any, number, boolean | Returns a table with n copies of val. | ||
scan( enum, fn, [accumulator|enum[1]], [clone|false] ) | table, function, any, boolean/nil | Same as reduce() but each step is appended to a table. This table is then returned. | ||
slice( enum, [start|1], [stop|#enum], [clone|false] ) | table, number/nil, number/nil, boolean/nil | Returns a table containing all the elements of enum between the start and stop indices. The start and stop indices are inclusive. | ||
split( enum, count, [clone|false] ) | table, number, boolean/nil | Returns two tables where the first is equivalent to slice( enum, 1, count ) and the second slice( enum, count+1, #enum ) . | ||
sum( enum, [clone|false] ) | table, boolean/nil | Returns the sum of all array elements in enum . | ||
take( enum, count, [clone|false] ) | table, number, boolean/nil | Returns only the first table of split( enum, count ) . | ||
take_every( enum, n, [clone|false] ) | table, number, boolean/nil | Returns a table containing every nth element of enum . | ||
unique( enum, [fn], [clone|false] ) | table, function/nil, boolean/nil | Returns a new table where all duplicate values in enum are removed. In case a duplicate is present, the element with the lowest index will be kept and every subsequent duplicate element is removed. fn can be used to create a custom id for every element so that the result is a table with elements which all create a unique id. If no function is given function( item ) return item end is used. | ||
zip( enums, [clone|false] ) | table, boolean/nil | Groups elements with the same indexes from different arrays together, i.e. zip{ {a1, a2, a3}, {b1, b2, b3}, {c1, c2} } -> {{a1, b1, c1}, {a2, b2, c2}, {a3, b3}} |
-- <nowiki> awawa local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local checkTypeMulti = libraryUtil.checkTypeMulti local p = {} p.__index = p setmetatable(p, { __call = function(_, enum) return p.new(enum) end }) function p.__tostring(enum) local dumpObject = require('Module:Logger').dumpObject setmetatable(enum, nil) return dumpObject(enum, {clean=true, collapseLimit=100}) end function p.__concat(lhs, rhs) if type(lhs) == 'table' and type(rhs) == 'table' then return p.insert(lhs, rhs) else return tostring(lhs) .. tostring(rhs) end end function p.__unm(enum) return p.map(enum, function(x) return -x end) end local function mathTemplate(lhs, rhs, funName, fun) checkTypeMulti('Module:Enum.' .. funName, 1, lhs, {'number', 'table'}) checkTypeMulti('Module:Enum.' .. funName, 2, rhs, {'number', 'table'}) local res = setmetatable({}, getmetatable(lhs) or getmetatable(rhs)) if type(lhs) == 'number' or type(rhs) == 'number' then local scalar, vector if type(lhs) == 'number' then scalar = lhs vector = rhs else scalar = rhs vector = lhs end for i = 1, #vector do res[i] = fun(vector[i], scalar) end else assert(#lhs == #rhs, 'Tables are not equal length') for i = 1, #lhs do res[i] = fun(lhs[i], rhs[i]) end end return res end function p.__add(lhs, rhs) return mathTemplate(lhs, rhs, '__add', function(x, y) return x + y end) end function p.__sub(lhs, rhs) return mathTemplate(lhs, rhs, '__sub', function(x, y) return x - y end) end function p.__mul(lhs, rhs) return mathTemplate(lhs, rhs, '__mul', function(x, y) return x * y end) end function p.__div(lhs, rhs) return mathTemplate(lhs, rhs, '__div', function(x, y) return x / y end) end function p.__pow(lhs, rhs) return mathTemplate(lhs, rhs, '__pow', function(x, y) return x ^ y end) end function p.__lt(lhs, rhs) for i = 1, math.min(#lhs, #rhs) do if lhs[i] >= rhs[i] then return false end end return true end function p.__le(lhs, rhs) for i = 1, math.min(#lhs, #rhs) do if lhs[i] > rhs[i] then return false end end return true end function p.__eq(lhs, rhs) if #lhs ~= #rhs then return false end for i = 1, #lhs do if lhs[i] ~= rhs[i] then return false end end return true end function p.all(enum, fn, clone) checkType('Module:Enum.all', 1, enum, 'table') checkType('Module:Enum.all', 2, fn, 'function', true) checkType('Module:Enum.all', 3, clone, 'boolean', true) if clone then enum = mw.clone(enum) end fn = fn or function(item) return item end local i = 1 while enum[i] ~= nil do if not fn(enum[i], i) then return false end i = i + 1 end return true end function p.any(enum, fn, clone) checkType('Module:Enum.any', 1, enum, 'table') checkType('Module:Enum.any', 2, fn, 'function', true) checkType('Module:Enum.any', 3, clone, 'boolean', true) if clone then enum = mw.clone(enum) end fn = fn or function(item) return item end local i = 1 while enum[i] ~= nil do if fn(enum[i], i) then return true end i = i + 1 end return false end function p.contains(enum, elem, clone) checkType('Module:Enum.contains', 1, enum, 'table') checkType('Module:Enum.contains', 3, clone, 'boolean', true) if clone then enum = mw.clone(enum); elem = mw.clone(elem) end return p.any(enum, function(item) return item == elem end) end function p.each(enum, fn, clone) checkType('Module:Enum.each', 1, enum, 'table') checkType('Module:Enum.each', 2, fn, 'function') checkType('Module:Enum.each', 3, clone, 'boolean', true) if clone then enum = mw.clone(enum) end local i = 1 while enum[i] ~= nil do fn(enum[i], i) i = i + 1 end end function p.filter(enum, fn, clone) checkType('Module:Enum.filter', 1, enum, 'table') checkType('Module:Enum.filter', 2, fn, 'function', true) checkType('Module:Enum.filter', 3, clone, 'boolean', true) if clone then enum = mw.clone(enum) end fn = fn or function(item) return item end local r = setmetatable({}, getmetatable(enum)) local len = 0 local i = 1 while enum[i] ~= nil do if fn(enum[i], i) then len = len + 1 r[len] = enum[i] end i = i + 1 end return r end function p.find(enum, fn, default, clone) checkType('Module:Enum.find', 1, enum, 'table') checkType('Module:Enum.find', 2, fn, 'function') checkType('Module:Enum.find', 4, clone, 'boolean', true) if clone then enum = mw.clone(enum); default = mw.clone(default) end local i = 1 while enum[i] ~= nil do if fn(enum[i], i) then return enum[i], i end i = i + 1 end return default end function p.find_index(enum, fn, default, clone) checkType('Module:Enum.find_index', 1, enum, 'table') checkType('Module:Enum.find_index', 2, fn, 'function') checkType('Module:Enum.find_index', 4, clone, 'boolean', true) if clone then enum = mw.clone(enum); default = mw.clone(default) end fn = fn or function(item) return item end local i = 1 while enum[i] ~= nil do if fn(enum[i], i) then return i end i = i + 1 end return default end function p.newIncrementor(start, step) checkType('Module:Enum.newIncrementor', 1, start, 'number', true) checkType('Module:Enum.newIncrementor', 2, step, 'number', true) step = step or 1 local n = (start or 1) - step local obj = {} return setmetatable(obj, { __call = function() n = n + step return n end, __tostring = function() return n end, __index = function() return n end, __newindex = function(self, k, v) if k == 'step' and type(v) == 'number' then step = v elseif type(v) == 'number' then n = v end end, __concat = function(x, y) return tostring(x) .. tostring(y) end }) end function p.intersect(enum1, enum2, clone) checkType('Module:Enum.intersect', 1, enum1, 'table') checkType('Module:Enum.intersect', 2, enum2, 'table') checkType('Module:Enum.intersect', 3, clone, 'boolean', true) if clone then enum1 = mw.clone(enum1); enum2 = mw.clone(enum2) end local enum2Elements = {} local res = setmetatable({}, getmetatable(enum1) or getmetatable(enum2)) local len = 0 p.each(enum2, function(item) enum2Elements[item] = true end) p.each(enum1, function(item) if enum2Elements[item] then len = len + 1 res[len] = item end end) return res end function p.intersects(enum1, enum2, clone) checkType('Module:Enum.intersects', 1, enum1, 'table') checkType('Module:Enum.intersects', 2, enum2, 'table') checkType('Module:Enum.intersects', 3, clone, 'boolean', true) if clone then enum1 = mw.clone(enum1); enum2 = mw.clone(enum2) end local small = {} local large if #enum1 <= #enum2 then p.each(enum1, function(item) small[item] = true end) large = enum2 else p.each(enum2, function(item) small[item] = true end) large = enum1 end return p.any(large, function(item) return small[item] end) end function p.insert(enum1, enum2, index, clone) checkType('Module:Enum.insert', 1, enum1, 'table') checkType('Module:Enum.insert', 2, enum2, 'table') checkType('Module:Enum.insert', 3, index, 'number', true) checkType('Module:Enum.insert', 4, clone, 'boolean', true) if clone then enum1 = mw.clone(enum1); enum2 = mw.clone(enum2) end local len1 = #enum1 local len2 = #enum2 index = index or (len1 + 1) local res = setmetatable({}, getmetatable(enum1) or getmetatable(enum2)) for i = 1, (len1 + len2) do if i < index then res[i] = enum1[i] elseif i < (index + len2) then res[i] = enum2[i - index + 1] else res[i] = enum1[i - len2] end end return res end function p.map(enum, fn, clone) checkType('Module:Enum.map', 1, enum, 'table') checkType('Module:Enum.map', 2, fn, 'function') checkType('Module:Enum.map', 3, clone, 'boolean', true) if clone then enum = mw.clone(enum) end local len = 0 local r = setmetatable({}, getmetatable(enum)) local i = 1 while enum[i] ~= nil do local tmp = fn(enum[i], i) if tmp ~= nil then len = len + 1 r[len] = tmp end i = i + 1 end return r end function p.max_by(enum, fn, clone) checkType('Module:Enum.max_by', 1, enum, 'table') checkType('Module:Enum.max_by', 2, fn, 'function') checkType('Module:Enum.max_by', 3, clone, 'boolean', true) if clone then enum = mw.clone(enum) end return unpack(p.reduce(enum, function(new, old) local y = fn(new) return y > old[2] and {new, y} or old end, {enum[1], -math.huge})) end function p.new(enum) for _, v in pairs(enum) do if type(v) == 'table' then p.new(v) end end if getmetatable(enum) == nil then setmetatable(enum, p) end return enum end function p.range(start, stop, step) checkType('Module:Enum.range', 1, start, 'number') checkType('Module:Enum.range', 2, stop, 'number', true) checkType('Module:Enum.range', 3, step, 'number', true) local array = setmetatable({}, p) local len = 0 if not stop then stop = start start = 1 end for i = start, stop, step or 1 do len = len + 1 array[len] = i end return array end function p.reduce(enum, fn, accumulator, clone) checkType('Module:Enum.reduce', 1, enum, 'table') checkType('Module:Enum.reduce', 2, fn, 'function') checkType('Module:Enum.reduce', 4, clone, 'boolean', true) if clone then enum = mw.clone(enum); accumulator = mw.clone(accumulator) end local acc = accumulator local i = 1 while enum[i] ~= nil do if i == 1 and not accumulator then acc = enum[i] else acc = fn(enum[i], acc) end i = i + 1 end return acc end function p.reject(enum, fn, clone) checkType('Module:Enum.reject', 1, enum, 'table') checkTypeMulti('Module:Enum.reject', 2, fn, {'function', 'table', 'nil'}) checkType('Module:Enum.reject', 3, clone, 'boolean', true) if clone then enum = mw.clone(enum) end fn = fn or function(item) return item end local r = setmetatable({}, getmetatable(enum)) local len = 0 if type(fn) == 'function' then local i = 1 while enum[i] ~= nil do if not fn(enum[i], i) then len = len + 1 r[len] = enum[i] end i = i + 1 end else local rejectMap = {} p.each(fn, function(item) rejectMap[item] = true end) local i = 1 while enum[i] ~= nil do if not rejectMap[enum[i]] then len = len + 1 r[len] = enum[i] end i = i + 1 end end return r end function p.rep(val, n, clone) checkType('Module:Enum.rep', 2, n, 'number') checkType('Module:Enum.reject', 3, clone, 'boolean', true) if clone then val = mw.clone(val) end local r = setmetatable({}, p) for i = 1, n do r[i] = val end return r end function p.scan(enum, fn, accumulator, clone) checkType('Module:Enum.scan', 1, enum, 'table') checkType('Module:Enum.scan', 2, fn, 'function') checkType('Module:Enum.scan', 4, clone, 'boolean', true) if clone then enum = mw.clone(enum); accumulator = mw.clone(accumulator) end local acc = accumulator local r = setmetatable({}, getmetatable(enum)) local i = 1 while enum[i] ~= nil do if i == 1 and not accumulator then acc = enum[i] else acc = fn(enum[i], acc) end r[i] = acc i = i + 1 end return r end function p.slice(enum, start, finish, clone) checkType('Module:Enum.slice', 1, enum, 'table') checkType('Module:Enum.slice', 2, start, 'number', true) checkType('Module:Enum.slice', 3, finish, 'number', true) checkType('Module:Enum.slice', 4, clone, 'boolean', true) if clone then enum = mw.clone(enum) end start = start or 1 finish = finish or #enum local r = setmetatable({}, getmetatable(enum)) local len = 0 for i = start, finish do len = len + 1 r[len] = enum[i] end return r end function p.split(enum, count, clone) checkType('Module:Enum.split', 1, enum, 'table') checkType('Module:Enum.split', 2, count, 'number') checkType('Module:Enum.split', 3, clone, 'boolean', true) if clone then enum = mw.clone(enum) end if #enum < count then return enum, {} elseif count < 1 then return {}, enum end local x = setmetatable({}, getmetatable(enum)) local y = setmetatable({}, getmetatable(enum)) for i = 1, #enum do table.insert(i <= count and x or y, enum[i]) end return x, y end function p.sum(enum, clone) checkType('Module:Enum.sum', 1, enum, 'table') checkType('Module:Enum.sum', 2, clone, 'boolean', true) if clone then enum = mw.clone(enum) end return p.reduce(enum, function(x, y) return x + y end) end function p.take(enum, count, clone) checkType('Module:Enum.take', 1, enum, 'table') checkType('Module:Enum.take', 2, count, 'number') checkType('Module:Enum.take', 3, clone, 'boolean', true) if clone then enum = mw.clone(enum) end local x, _ = p.split(enum, count) return x end function p.take_every(enum, n, clone) checkType('Module:Enum.take_every', 1, enum, 'table') checkType('Module:Enum.take_every', 2, n, 'number') checkType('Module:Enum.take_every', 3, clone, 'boolean', true) if clone then enum = mw.clone(enum) end local r = setmetatable({}, getmetatable(enum)) local len = 0 local i = 1 while enum[i] ~= nil do if (i - 1) % n == 0 then len = len + 1 r[len] = enum[i] end i = i + 1 end return r end function p.unique(enum, fn, clone) checkType('Module:Enum.unique', 1, enum, 'table') checkType('Module:Enum.unique', 2, fn, 'function', true) checkType('Module:Enum.unique', 3, clone, 'boolean', true) if clone then enum = mw.clone(enum) end fn = fn or function(item) return item end local r = setmetatable({}, getmetatable(enum)) local len = 0 local hash = {} local i = 1 while enum[i] ~= nil do local id = fn(enum[i]) if not hash[id] then len = len + 1 r[len] = enum[i] hash[id] = true end i = i + 1 end return r end function p.zip(enums, clone) checkType('Module:Enum.zip', 1, enums, 'table') checkType('Module:Enum.zip', 2, clone, 'boolean', true) if clone then enums = mw.clone(enums) end local r = setmetatable({}, getmetatable(enums)) local _, longest = p.max_by(enums, function(enum) return #enum end) for i = 1, longest do local q = {} for j = 1, #enums do table.insert(q, enums[j][i]) end table.insert(r, q) end return r end return p -- </nowiki>