たくさんの場所で使っている関数があるので、新しいモジュールに同じ関数をコピーし続けるのではなく、ここで統一することにしました。
これをどのように使うかというと:
- 新しいモジュールを作るときには、トップの近くにこれを追加します。:
local Shared = require( "Module:Shared" )
- これらの関数のいずれかを呼び出す必要がある場合は、"Shared "と前置きしてください。例えば、tableCountを次のように呼び出すことができます。:
Shared.tableCount(data)
これはUser:Falterfireによって最初にまとめられていますが、これらの機能はすべて私のものではありません。私はそれをトレースできるところで原著者を引用しました。 This is being initially pulled together by User:Falterfire, but not all these functions are mine. I've cited original author where I can trace it
--- '''Shared''' contains useful utilities, including extensions of STL libraries.<br />
--
-- On this Wiki, Shared is used in:
-- * [[Module:Acquisition]]
-- * [[Module:Ability]]
-- * [[Module:Arcane]]
-- * [[Module:Avionics]]
-- * [[Module:Cost]]
-- * [[Module:DamageTypes]]
-- * [[Module:Decorations]]
-- * [[Module:DropTables]]
-- * [[Module:Focus]]
-- * [[Module:Lua]]
-- * [[Module:MasteryRank]]
-- * [[Module:Maximization]]
-- * [[Module:Missions]]
-- * [[Module:Mods]]
-- * [[Module:Stances]]
-- * [[Module:Version]]
-- * [[Module:Void]]
-- * [[Module:VoidByReward]]
-- * [[Module:Warframes]]
-- * [[Module:Weapons]]
--
-- @module shared
-- @alias p
-- @author [[User:FINNER|FINNER]]
-- @author [[User:Cephalon Scientia|Cephalon Scientia]]
-- @attribution [[User:Falterfire|Falterfire]]
-- @attribution [[User:Cephalon Scientia|Cephalon Scientia]]
-- @attribution [[User:FINNER|FINNER]]
-- @attribution [[User:Gigamicro|Gigamicro]]
-- @attribution [[User:NoBrainz|NoBrainz]]
-- @image
-- @require [[Module:Math]]
-- @require [[Module:String]]
-- @require [[w:c:dev:Module:Arguments|Module:Arguments]]
-- @release stable
-- <nowiki>
local p = {}
-- Module Dependencies -------------------------------------------------------
-- TODO: Add math and string variables to package so other modules that require M:Shared can access
-- STL extension functions via shared.math.func() syntax?
local math = require('Module:Math');
local string = require('Module:String');
-- local table = require('Module:Table'); -- M:Tables is next STL extension library to be added
local Args = require('Dev:Arguments');
-- Adding M:Math functions to M:Shared package
for k, v in pairs(math) do p[k] = v end
-- Adding M:String functions to M:Shared package
for k, v in pairs(string) do p[k] = v end
--- For getting frame or parent arguments.
-- @function p.getArgs
-- @param {table} frame The input arguments
-- @param {table} options Options for getting the args
-- @return {table} The arguments
function p.getArgs(frame, options)
if type(frame[1]) == 'table' and table.getn(frame) < 2 then frame = frame[1]; end
if type(options) ~= 'table' then options = {options}; end
local args = Args.getArgs(frame, options);
local tempArgs = {};
local str;
if options.replace then
for i, v in pairs(args) do
if type(i) ~= 'number' or type(v) ~= 'string' then tempArgs[i] = v;
else
str = '('..math.replace(v)..')';
if options.eval then tempArgs[i] = tonumber(math.eval(str));
else tempArgs[i] = str; end
end
end
args = tempArgs;
end
local j = 1;
tempArgs = {};
if options.noNil then
for i, v in pairs(args) do
if type(i) ~= 'number' then tempArgs[i] = v;
elseif v then tempArgs[j] = v; j = j + 1; end
end
args = tempArgs;
end
return args;
end
-- TODO: Extract value finding in a table functionality into a separate function. Call it hasValue()
-- Right now function name conflicts with M:String's contains()
--- Checks if a string is in a table or is a substring of a string
-- @function p.contains
-- @param {table, string} list A table or a string
-- @param {string} item The element that is being searched for
-- @param {boolean} ignoreCase If false, search is case-sensitive; true otherwise
-- @return {boolean} True if element exists in List, false otherwise
function p.contains(list, item, ignoreCase)
if (list == nil or item == nil) then
return false
end
if (ignoreCase == nil) then
ignoreCase = false
end
if (type(list) == "table") then
for _, value in pairs(list) do
if (value == item) then
return true
elseif (ignoreCase and string.upper(value) == string.upper(item)) then
return true
end
end
else
local start = string.find(list, item)
return start ~= nil
end
return false
end
--- Iterator sorted by keys.<br />
-- For example, for a table `data = {["Cat"] = 5, ["Bat"] = 4, ["Hat"] = 7 }`<br />
-- `for k, v in skpairs(data) do print(('k="$s", v=%d'):format(k, v)) end`<br />
-- would loop through:<br />k="Bat", v=4<br />k="Cat", v=5<br />k="Hat", v=7<br />
-- By u:gigamicro
-- @function p.skpairs
-- @param {table} t A table to be sorted
-- @param {boolean} sortDescending If true, sort by descending order; false otherwise
-- @return {function} Sorted iterators
function p.skpairs(t, sortType)
local keys = {}
for k in pairs(t) do keys[#keys + 1] = k end
if type(sortType) == 'function' then
table.sort(keys, sortType)--custom sort (always applied to keys)
elseif sortType then--descending
table.sort(keys, function(a, b) return a > b end)
else
table.sort(keys)--implicit <, function(a, b) return a < b end)>
end
local invkeys = {}
for i, k in ipairs(keys) do
invkeys[k]=i
end
return function(tab, k)
local key = tab[2][(tab[1][k] or 0)+1]
return key, t[key]
end, {invkeys,keys}, startingkey
end
--Loops through all the Relic types
--Comes up a surprising amount
--rework 11/9/2020 by u:gigamicro
-- TODO: Move Shared.relicLoop() to in M:Void or M:VoidByReward
function p.relicLoop()
return function(_, lastTier)
return ({ ['']='Lith', ['Lith']='Meso', ['Meso']='Neo', ['Neo']='Axi' })[lastTier]
end, _, ''
end
function p.consoleLoop()
return function(_, lastTier)
return ({['']='PC', ['PC']='PS4', ['PS4']='XB1', ['XB1']='NSW'})[lastTier]
end, _, ''
end
--- Returns the number of elements/entries in a table.
-- Originally from Module:VoidByReward written by User:NoBrainz.
-- @function p.tableCount
-- @param {table} table A table with no explicit nil values
-- @return {number} The size of table, ignoring keys with nil values and
-- nil values themselves
function p.tableCount(table)
assert(type(table) == 'table', 'p.tableCount(table): table is not of type "table"')
local count = 0
for _ in pairs(table) do count = count + 1 end
return count
end
--- Returns the number of indexed elements in a table.
-- @function p.indexCount
-- @param {table} t A table with no explicit nil values
-- @return {number} The number of indexed elements in a table;
-- if table is not of type 'table' then return nil
function p.indexCount(t)
if (type(t) == 'table') then
local count = 0
for _ in ipairs(t) do count = count + 1 end
return count
else
return nil
end
end
--- Sorts a table based on the listed column.
-- @function p.tableSort
-- @param {table} t Table to be sorted
-- @param {string} sortCol Name of column to be sorted by
-- @param {boolean} sortAscend If true, sorts in ascending order by specified column; false otherwise
function p.tableSort(t, sortCol, sortAscend)
local function comparator(r1, r2)
if sortAscend then
return r1[sortCol] < r2[sortCol]
else
return r1[sortCol] > r2[sortCol]
end
end
table.sort(t, comparator)
end
--- Checks to see if a key exists in a given nested table.
-- @function p.hasKey
-- @param {string} table A nested table
-- @param {string} key Key name
-- @param {number} length Represents the size of outer table (optional)
-- @return {boolean} True if key exists in table, false otherwise or if key contains a nil value
function p.hasKey(table, key, length)
if (length == nil) then
length = p.tableCount(table)
end
-- iterating through outer table
for i = 1, length, 1 do
local elem = table[i] -- storing one of inner tables into a variable
if (elem[key] ~= nil) then
return true
end
end
return false
end
--upk by [[User:gigamicro]], sanitizes any object to a string
do
local conversion = {
string=function(v)
v = v:gsub('\n','\\n'):gsub('%c',function(s) return '\\'..s:byte() end)
if not v:match"'" then
return "'"..v.."'"
elseif not v:match '"' then
return '"'..v..'"'
else
local n=0; while v:match(']'..(('='):rep(n))..']') do n=n+1 end; local s = (('='):rep(n)); return table.concat{'[',s,'[',v,']',s,']'}
end
end,
boolean=function(v) return v and 'true' or 'false' end,
number=function(v) return tostring(v) end,
table=function(v, linedepth)
local str = {'{'}
local index = 1
if linedepth and linedepth > 0 then table.insert(str, '\n') end
for k,val in pairs(v) do
--print (k, '(', type(val), ')')
if k==index then index=index+1 else table.insert(str, '['..p.upk(k)..'] = ') end
if v ~= val and k~='_G' and k~='loaded' then
table.insert(str, p.upk(val, linedepth and linedepth>0 and linedepth-1))
else
table.insert(str, '<repeat>')
end --print (k,'=',str[#str])
table.insert(str, ', ')
if linedepth and linedepth>0 then table.insert(str, '\n') end
end
table.insert(str,'}')
--if print then print (table.concat(str)) end
return table.concat(str)
end,
['function'] = function() return '<function>' end,--function()end' end,
['nil'] = function() return 'nil' end,
userdata = function() return '<userdata>' end,
thread = function() return '<thread>' end,
}
function p.upk(v, linedepth) return conversion[type(v)](v,linedepth) end
--(conversion[type(v)..'e'] or function(v,ld) error(type(v)..' is not a recognized type') end)(v, linedepth or 0) end
end--upk
-- @function p.Cache
-- @author Gigamicro
-- @param {string} s
-- @return {string}
function p.Cache(frame) return p.upk(require(frame.args[1])[frame.args[2]][frame.args[3]]) end
return p