nomsu/utils.moon
2017-08-20 01:30:04 -07:00

117 lines
3.3 KiB
Plaintext

local utils
utils = {
is_list: (t)->
i = 1
for _ in pairs(t)
if t[i] == nil then return false
i += 1
return true
repr: (x, add_quotes=false)->
switch type(x)
when 'table'
if utils.is_list x
"{#{table.concat([utils.repr(i, true) for i in *x], ", ")}}"
else
"{#{table.concat(["[#{utils.repr(k, true)}]: #{utils.repr(v, true)}" for k,v in pairs x], ", ")}}"
when 'string'
if not add_quotes
x
elseif not x\find[["]]
"\"#{x}\""
elseif not x\find[[']]
"\'#{x}\'"
else
for i=0,math.huge
eq = ("=")\rep(i)
if not x\find"%[#{eq}%[" and not x\find"%]#{eq}%]"
return "[#{eq}[#{x}]#{eq}]"
else
tostring(x)
split: (str, sep="%s")->
[chunk for chunk in str\gmatch("[^#{sep}]")]
keys: (t)-> [k for k in pairs(t)]
values: (t)-> [v for _,v in pairs(t)]
sum: (t)->
with tot = 0
for _,x in pairs(t) do tot += x
all: (t)->
for _,x in pairs t
if not x then return false
return true
any: (t)->
for _,x in pairs t
if x then return true
return false
min: (list, keyFn=((x)->x))->
assert utils.is_list(list), "min() expects to be operating on a list"
with best = list[1]
if type(keyFn) == 'table'
keyTable = keyFn
keyFn = (k)->keyTable[k]
for i=2,#list
if keyFn(list[i]) < keyFn(best)
best = list[i]
max: (list, keyFn=((x)->x))->
assert utils.is_list(list), "min() expects to be operating on a list"
with best = list[1]
if type(keyFn) == 'table'
keyTable = keyFn
keyFn = (k)->keyTable[k]
for i=2,#list
if keyFn(list[i]) > keyFn(best)
best = list[i]
sort: (list, keyFn=((x)->x), reverse=false)->
assert utils.is_list(list), "min() expects to be operating on a list"
if type(keyFn) == 'table'
keyTable = keyFn
keyFn = (k)->keyTable[k]
comparison = if reverse then ((x,y)->(keyFn(x)>keyFn(y))) else ((x,y)->(keyFn(x)<keyFn(y)))
table.sort list, comparison
equivalent: (x,y)->
if x == y then return true
if type(x) != type(y) then return false
if type(x) != 'table' then return false
for k,v in pairs(x)
if y[k] != v
return false
for k,v in pairs(y)
if x[k] != v
return false
return true
key_for: (t, value)->
for k,v in pairs(t)
if v == value
return k
return nil
clamp: (x, min,max)->
if x < min then min
elseif x > max then max
else x
mix: (min,max, amount)->
(1-amount)*min + amount*max
sign: (x)->
if x == 0 then 0
elseif x < 0 then -1
else 1
round: (x, increment=1)->
if x >= 0 then math.floor(x/increment + .5)*increment
else math.ceil(x/increment - .5)*increment
}
return utils