12,704
edits
Falterfire (talk | contribs) (Copied over some handy shared functions I'll probably need later.) |
(Replace GCD function with an implementation of the Euclidean algorithm, so that fewer iterations occur when numbers differ greatly in magnitude) |
||
(11 intermediate revisions by one other user not shown) | |||
Line 44: | Line 44: | ||
end | end | ||
return iterator | return iterator | ||
end | |||
--General purpose function for going through a table after sorting based on a custom sort order | |||
--Taken from https://stackoverflow.com/questions/15706270/sort-a-table-in-lua | |||
function p.spairs(t, order) | |||
-- collect the keys | |||
local keys = {} | |||
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, | |||
-- otherwise just sort the keys | |||
if order then | |||
table.sort(keys, function(a,b) return order(t, a, b) end) | |||
else | |||
table.sort(keys) | |||
end | |||
-- return the iterator function | |||
local i = 0 | |||
return function() | |||
i = i + 1 | |||
if keys[i] then | |||
return keys[i], t[keys[i]] | |||
end | |||
end | |||
end | end | ||
Line 152: | Line 178: | ||
if(maxDigits ~= nil and decimals > maxDigits) then | if(maxDigits ~= nil and decimals > maxDigits) then | ||
result = tonumber(string.format("%."..maxDigits.."f", result)) | result = string.format("%."..minDigits.."f", tonumber(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) | ||
Line 182: | Line 208: | ||
for key, value in pairs(List) do | for key, value in pairs(List) do | ||
if (value == Item) then | if (value == Item) then | ||
return true | 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 | return true, key | ||
end | end | ||
end | end | ||
Line 234: | Line 260: | ||
end | end | ||
-- copies the contents of a variable; for | -- copies the contents of a variable; handy for when you might want to modify an object taken from a data file | ||
-- | -- or any other read-only variable | ||
-- | -- Stolen from https://gist.github.com/tylerneylon/81333721109155b2d244 | ||
-- | function p.clone(obj) | ||
- | if type(obj) ~= 'table' then return obj end | ||
local res = {} | |||
for k, v in pairs(obj) do res[p.clone(k)] = p.clone(v) end | |||
return res | |||
end | |||
if | |||
-- Euclidean Greatest Common Divisor algorithm | |||
function p.gcd(a, b) | |||
if b ~= 0 then | |||
return p.gcd(b, a % b) | |||
else | |||
return math.abs(a) | |||
end | |||
end | |||
--Formats a pair of numbers as a reduced fraction | |||
function p.fraction(n, d) | |||
local gcd = p.gcd(n, d) | |||
return p.formatnum(n/gcd)..'/'..p.formatnum(d/gcd) | |||
end | |||
function p.timeString(timeInSeconds, shorten) | |||
local remain = timeInSeconds | |||
local days, hours, minutes = 0, 0, 0 | |||
local isShort = shorten | |||
local pieces = {} | |||
if remain >= 86400 then | |||
days = math.floor(remain / 86400) | |||
remain = remain - days * 86400 | |||
if isShort then | |||
table.insert(pieces, days..'d') | |||
elseif days > 1 then | |||
table.insert(pieces, days..' days') | |||
else | |||
table.insert(pieces, days..' day') | |||
end | |||
end | |||
if remain >= 3600 then | |||
hours = math.floor(remain / 3600) | |||
remain = remain - hours * 3600 | |||
if isShort then | |||
table.insert(pieces, hours..'h') | |||
elseif hours > 1 then | |||
table.insert(pieces, hours..' hours') | |||
else | |||
table.insert(pieces, hours..' hour') | |||
end | |||
end | |||
if remain >= 60 then | |||
minutes = math.floor(remain / 60) | |||
remain = remain - minutes * 60 | |||
if isShort then | |||
table.insert(pieces, minutes..'m') | |||
elseif minutes > 1 then | |||
table.insert(pieces, minutes..' minutes') | |||
else | |||
table.insert(pieces, minutes..' minutes') | |||
end | |||
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 | |||
function p.fixPagename(pageName) | |||
local result = pageName | |||
result = string.gsub(result, "%%27", "'") | |||
result = string.gsub(result, "'", "'") | |||
return result | |||
end | |||
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 | ||
end | |||
return true | |||
end | end | ||
return p | return p |