Anonymous

Module:Shared: Difference between revisions

From Melvor Idle
formatnum: Use faster variant of function
(Added timeString function)
(formatnum: Use faster variant of function)
(14 intermediate revisions by 3 users not shown)
Line 25: Line 25:
--Originally snagged this from Module:VoidByReward written by User:NoBrainz
--Originally snagged this from Module:VoidByReward written by User:NoBrainz
function p.skpairs(t, revert)
function p.skpairs(t, revert)
    local keys = {}
local keys = {}
    for k in pairs(t) do keys[#keys + 1] = k end
for k in pairs(t) do keys[#keys + 1] = k end
    if revert ~= nil then
if revert ~= nil then
        table.sort(keys, function(a, b) return a > b end)
table.sort(keys, function(a, b) return a > b end)
    else
else
        table.sort(keys)
table.sort(keys)
    end
end
   
   
    local i = 0
local i = 0
    local iterator = function()
local iterator = function()
        i = i + 1
i = i + 1
        local key = keys[i]
local key = keys[i]
        if key then
if key then
            return key, t[key]
return key, t[key]
        else
else
            return nil
return nil
        end
end
    end
end
    return iterator
return iterator
end
end


Line 50: Line 50:
--Taken from https://stackoverflow.com/questions/15706270/sort-a-table-in-lua
--Taken from https://stackoverflow.com/questions/15706270/sort-a-table-in-lua
function p.spairs(t, order)
function p.spairs(t, order)
    -- collect the keys
-- collect the keys
    local keys = {}
local keys = {}
    for k in pairs(t) do keys[#keys+1] = k end
for k in pairs(t) do keys[#keys+1] = k end


    -- if order function given, sort by it by passing the table and keys a, b,
-- if order function given, sort by it by passing the table and keys a, b,
    -- otherwise just sort the keys  
-- otherwise just sort the keys  
    if order then
if order then
        table.sort(keys, function(a,b) return order(t, a, b) end)
table.sort(keys, function(a,b) return order(t, a, b) end)
    else
else
        table.sort(keys)
table.sort(keys)
    end
end


    -- return the iterator function
-- return the iterator function
    local i = 0
local i = 0
    return function()
return function()
        i = i + 1
i = i + 1
        if keys[i] then
if keys[i] then
            return keys[i], t[keys[i]]
return keys[i], t[keys[i]]
        end
end
    end
end
end
end
   
   
Line 76: Line 76:
--Originally snagged this from Module:VoidByReward written by User:NoBrainz
--Originally snagged this from Module:VoidByReward written by User:NoBrainz
function p.titleCase(head, tail)
function p.titleCase(head, tail)
    if tail == nil then
if tail == nil then
        --Split into two lines because don't want the other return from gsub
--Split into two lines because don't want the other return from gsub
        local result = string.gsub(head, "(%a)([%w_']*)", p.titleCase)
local result = string.gsub(head, "(%a)([%w_']*)", p.titleCase)
        return result
return result
    else
else
        return string.upper(head) .. string.lower(tail)
return string.upper(head) .. string.lower(tail)
    end
end
end
end
   
   
Line 97: Line 97:
--      if table is not of type 'table' then return nil
--      if table is not of type 'table' then return nil
function p.tableCount(table)
function p.tableCount(table)
    if (type(table) == 'table') then
if (type(table) == 'table') then
        local count = 0
local count = 0
        for _ in pairs(table) do count = count + 1 end
for _ in pairs(table) do count = count + 1 end
        return count
return count
    else
else
        return nil
return nil
    end
end
end
end
   
   
Line 111: Line 111:
--      if table is not of type 'table' then return nil
--      if table is not of type 'table' then return nil
function p.indexCount(table)
function p.indexCount(table)
    if (type(table) == 'table') then
if (type(table) == 'table') then
        local count = 0
local count = 0
        for _ in ipairs(table) do count = count + 1 end
for _ in ipairs(table) do count = count + 1 end
        return count
return count
    else
else
        return nil
return nil
    end
end
end
end
   
   
--Sorts theTable based on the listed column
--Sorts theTable based on the listed column
function p.tableSort(theTable, sortCol, ascend)
function p.tableSort(theTable, sortCol, ascend)
    local new  function sorter(r1, r2)
local new  function sorter(r1, r2)
                    if(ascend) then
if ascend then
                        return r1[sortCol] < r2[sortCol]
return r1[sortCol] < r2[sortCol]
                    else
else
                        return r1[sortCol] > r2[sortCol]
return r1[sortCol] > r2[sortCol]
                    end
end
                end
end
    table.sort(theTable, sorter)
table.sort(theTable, sorter)
end
end
   
   
Line 135: Line 135:
--For example calling splitString ("Lith V1 Relic", " ") would return {"Lith", "V1", "Relic"}
--For example calling splitString ("Lith V1 Relic", " ") would return {"Lith", "V1", "Relic"}
function p.splitString(inputstr, sep)
function p.splitString(inputstr, sep)
        if sep == nil then
if sep == nil then
                sep = "%s"
sep = "%s"
        end
end
        local t={}
local t = {}
        for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
                table.insert(t, str)
table.insert(t, str)
        end
end
        return t
return t
end
end
   
   
Line 148: Line 148:
--For example calling startsWith ("Lith V1 Relic", "Lith") would return true
--For example calling startsWith ("Lith V1 Relic", "Lith") would return true
function p.startsWith(string1, start)
function p.startsWith(string1, start)
    return string.sub(string1, 1, string.len(start)) == start
return string.sub(string1, 1, string.len(start)) == start
end
end
   
   
--Stolen from Stack Overflow
--Adds commas
--Adds commas
function p.formatnum(number)
function p.formatnum(number)
  local i, j, minus, int, fraction = tostring(number):find('([-]?)(%d+)([.]?%d*)')
if tonumber(number) == nil then
return number
  -- reverse the int-string and append a comma to all blocks of 3 digits
else
  int = int:reverse():gsub("(%d%d%d)", "%1,")
local result = number
while true do
  -- reverse the int-string back remove an optional comma and put the
-- Format in blocks of 3 digits at a time until formatting is complete
  -- optional minus and fractional part back
result, k = string.gsub(result, "^(-?%d+)(%d%d%d)", '%1,%2')
  return minus .. int:reverse():gsub("^,", "") .. fraction
if k == 0 then
break
end
end
return result
end
end
 
function p.formatNumber(frame)
number = frame.args ~= nil and frame.args[1] or frame
return p.formatnum(number)
end
end
 
function p.round(val, maxDigits, minDigits)
function p.round(val, maxDigits, minDigits)
    if(val == nil) then
if val == nil then
        return nil
return nil
    else
else
        if(type(maxDigits) == "table") then
if type(maxDigits) == "table" then
            minDigits = maxDigits[2]
minDigits = maxDigits[2]
            maxDigits = maxDigits[1]
maxDigits = maxDigits[1]
        end
end
   
   
        local result = val..""
local result = val..""
        local decimals = string.find(result, "%.")
local decimals = string.find(result, "%.")
        if(decimals ~= nil ) then decimals = string.len(result) - decimals else decimals = 0 end
if decimals ~= nil then
decimals = string.len(result) - decimals
else
decimals = 0
end
   
   
        if(maxDigits ~= nil and decimals > maxDigits) then
if maxDigits ~= nil and decimals > maxDigits then
            result = tonumber(string.format("%."..maxDigits.."f", result))
result = string.format("%."..maxDigits.."f", result)
        elseif(minDigits ~= nil and decimals < minDigits) then
elseif minDigits ~= nil and decimals < minDigits then
            result = string.format("%."..minDigits.."f", result)
result = string.format("%."..minDigits.."f", result)
        end
end
   
   
        return result
return result
    end
end
end
end
   
   
--From http://lua-users.org/wiki/SimpleRound
--From http://lua-users.org/wiki/SimpleRound
function p.round2(num, numDecimalPlaces)
function p.round2(num, numDecimalPlaces)
    local mult = 10^(numDecimalPlaces or 0)
local mult = 10^(numDecimalPlaces or 0)
    return math.floor(num * mult + 0.5) / mult
return math.floor(num * mult + 0.5) / mult
end
end
   
   
Line 198: Line 211:
-- post: returns a boolean; true if element exists in List, false otherwise
-- post: returns a boolean; true if element exists in List, false otherwise
function p.contains(List, Item, IgnoreCase)
function p.contains(List, Item, IgnoreCase)
    if (List == nil or Item == nil) then  
if List == nil or Item == nil then  
        return false  
return false  
    end
end
    if(IgnoreCase == nil) then  
if IgnoreCase == nil then  
        IgnoreCase = false  
IgnoreCase = false  
    end
end
   
   
    if(type(List) == "table") then
if type(List) == "table" then
        for key, value in pairs(List) do
for key, value in pairs(List) do
            if (value == Item) then
if value == Item then
                return true, key
return true, key
            elseif (IgnoreCase and string.upper(value) == string.upper(Item)) then
elseif IgnoreCase and string.upper(value) == string.upper(Item) then
                return true, key
return true, key
            end
end
        end
end
    else
else
        local start = string.find(List, Item)
local start = string.find(List, Item)
        return start ~= nil
return start ~= nil
    end
end
    return false
return false
end
end
   
   
Line 234: Line 247:
--User:Giga Martin
--User:Giga Martin
function p.trim(str)
function p.trim(str)
  return (str:gsub("^%s*(.-)%s*$", "%1"))
return (str:gsub("^%s*(.-)%s*$", "%1"))
end
end
   
   
Line 246: Line 259:
--      if key contains a nil value
--      if key contains a nil value
function p.hasKey(table, key, length)
function p.hasKey(table, key, length)
    if (length == nil) then
if (length == nil) then
        length = p.tableCount(table)
length = p.tableCount(table)
    end
end
   
   
    -- iterating through outer table
-- iterating through outer table
    for i = 1, length, 1 do
for i = 1, length, 1 do
        local elem = table[i]  -- storing one of inner tables into a variable
local elem = table[i]  -- storing one of inner tables into a variable
        if (elem[key] ~= nil) then
if (elem[key] ~= nil) then
            return true
return true
        end
end
    end
end
    return false
return false
end
end
   
   
Line 264: Line 277:
-- Stolen from https://gist.github.com/tylerneylon/81333721109155b2d244
-- Stolen from https://gist.github.com/tylerneylon/81333721109155b2d244
function p.clone(obj)
function p.clone(obj)
    if type(obj) ~= 'table' then return obj end
if type(obj) ~= 'table' then return obj end
    local res = {}
local res = {}
    for k, v in pairs(obj) do res[p.clone(k)] = p.clone(v) end
for k, v in pairs(obj) do res[p.clone(k)] = p.clone(v) end
    return res
return res
end
end


-- Euclid's Greatest Common Divisor algorithm
-- Euclidean Greatest Common Divisor algorithm
function p.gcd(a, b)
function p.gcd(a, b)
  if(a == b) then
if b ~= 0 then
    return a
return p.gcd(b, a % b)
  else
else
    if(a > b) then
return math.abs(a)
      if b == 0 then
end
        return a
      else
        return p.gcd(a - b, b)
      end
    else
      if a == 0 then
        return b
      else
        return p.gcd(a, b - a)
      end
    end
  end
end
end


--Formats a pair of numbers as a reduced fraction
--Formats a pair of numbers as a reduced fraction
function p.fraction(n, d)
function p.fraction(n, d)
  local gcd = p.gcd(n, d)
local gcd = p.gcd(n, d)
  return p.formatnum(n/gcd)..'/'..p.formatnum(d/gcd)
return p.formatnum(n/gcd)..'/'..p.formatnum(d/gcd)
end
 
--Similar to p.fraction but returns the simplified numerator and denomerator separately without formatting
function p.fractionpair(n, d)
local gcd = p.gcd(n, d)
return n / gcd, d / gcd
end
end


function p.timeString(timeInSeconds)
function p.timeString(timeInSeconds, shorten)
  local remain = timeInSeconds
local remain = timeInSeconds
  local days, hours, minutes = 0, 0, 0
local days, hours, minutes = 0, 0, 0
 
local isShort = shorten
  local pieces = {}


  if remain >= 86400 then
local pieces = {}
    days = math.floor(remain / 86400)
 
    remain = remain - days * 86400
if remain >= 86400 then
    if days > 1 then
days = math.floor(remain / 86400)
      table.insert(pieces, days..' days')
remain = remain - days * 86400
    else
if isShort then
      table.insert(pieces, days..' day')
table.insert(pieces, days..'d')
    end
elseif days > 1 then
  end
table.insert(pieces, days..' days')
  if remain >= 3600 then
else
    hours = math.floor(remain / 3600)
table.insert(pieces, days..' day')
    remain = remain - hours * 3600
end
    if hours > 1 then
end
      table.insert(pieces, hours..' hours')
if remain >= 3600 then
    else
hours = math.floor(remain / 3600)
      table.insert(pieces, hours..' hour')
remain = remain - hours * 3600
    end
if isShort then
  end
table.insert(pieces, hours..'h')
  if remain >= 60 then
elseif hours > 1 then
    minutes = math.floor(remain / 60)
table.insert(pieces, hours..' hours')
    remain = remain - minutes * 60
else
    if minutes > 1 then
table.insert(pieces, hours..' hour')
      table.insert(pieces, minutes..' minutes')
end
    else
end
      table.insert(pieces, minutes..' minutes')
if remain >= 60 then
    end
minutes = math.floor(remain / 60)
  end
remain = remain - minutes * 60
  if remain > 0 then
if isShort then
    if remain > 1 then
table.insert(pieces, minutes..'m')
      table.insert(pieces, remain..' seconds')
elseif minutes > 1 then
    else
table.insert(pieces, minutes..' minutes')
      table.insert(pieces, remain..' second')
else
    end
table.insert(pieces, minutes..' minutes')
  end
end
  return table.concat(pieces, ', ')
end
if remain > 0 then
if isShort then
table.insert(pieces, remain..'s')
elseif remain > 1 then
table.insert(pieces, remain..' seconds')
else
table.insert(pieces, remain..' second')
end
end
return table.concat(pieces, ', ')
end
end
 
function p.fixPagename(pageName)
local result = pageName
result = string.gsub(result, "%%27", "'")
result = string.gsub(result, "&#39;", "'")
return result
end
 
--Checks if two tables contain the same value with the same indices
function p.tablesEqual(t1, t2)
if p.tableCount(t1) ~= p.tableCount(t2) then return false end
for i, val in p.skpairs(t1) do
if type(val) ~= type(t2[i]) then
return false
elseif type(val) == 'table' then
if not p.tablesEqual(val, t2[i]) then return false end
elseif t2[i] ~= val then
return false
end
end
return true
end
 
--Returns a number including the sign, even if positive
function p.numStrWithSign(number)
if number >= 0 then
return '+'..p.formatnum(number)
else
return p.formatnum(number)
end
end
 
return p
return p