Warframe日本語 Wiki
Advertisement

たくさんの場所で使っている関数があるので、新しいモジュールに同じ関数をコピーし続けるのではなく、ここで統一することにしました。

これをどのように使うかというと:

  1. 新しいモジュールを作るときには、トップの近くにこれを追加します。:
local Shared = require( "Module:Shared" )
  1. これらの関数のいずれかを呼び出す必要がある場合は、"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
Advertisement