aboutsummaryrefslogtreecommitdiff
path: root/utils.moon
blob: 3004c5847ba449a2ef148cf99b1654389ee4b128 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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)]
    set: (list)-> {i,true for i in *list}

    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