-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathenumerable.lua
More file actions
155 lines (140 loc) · 4.27 KB
/
enumerable.lua
File metadata and controls
155 lines (140 loc) · 4.27 KB
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
local enums = {}
enums.__index = enums
--- Constructor for the enumerator object.
-- Enumerator objects act as a wrappers for tables.
-- The object contains functions for manupilating table data
-- in a functional matter. For more information and examples
-- see the specific functions.
-- @param t Table or string that is to be iterated over.
-- @return enum object
local enum = function(t)
local ty = type(t)
if ty ~= "string" and ty ~= "table" then
error("Wrong argument. Expected table or string. Got " .. ty .. '.')
end
if ty == "string" then
local temp = {}
for i=1,#t do
temp[#temp+1] = string.sub(t,i,i)
end
t = temp
end
local e = setmetatable({}, enums)
e.table = t
return e
end
--- Iterate over each element of the enum and perform some actions on them.
-- @param fn Function that is to be executed on each element.
-- Function signature: fn(element, index) -> nil
function enums:each(fn)
for i,v in ipairs(self.table) do
fn(v,i)
end
end
--- Selects elements from a table.
-- select generates a new enum which only contains elements for which
-- pred function returns true.
-- @param pred Predicate function. Decides which elements are selected.
-- Function signature: pred(elem) -> boolean
-- @return New enum object with elements that were selected.
-- @see enums:filter
-- @see enums:reject
function enums:select(pred)
local t = {}
for _,v in ipairs(self.table) do
if pred(v) == true then
t[#t+1] = v
end
end
return enum(t)
end
--- @see enums:select
enums.filter = enums.select
--- Rejects elements of a table if the predicate returns true.
-- @param pred Predicate function. Decides which elements are dropped.
-- Function signature: pred(elem) -> boolean
-- @return New enum object with elements that were not rejected.
-- @see enums:select
function enums:reject(pred)
local t = {}
for _,v in ipairs(self.table) do
if pred(v) == false then
t[#t+1] = v
end
end
return enum(t)
end
--- Executes a function on each of the table elements and replaces
-- those elements with whatever the function returns.
-- @param fn Function to be executed on each element.
-- Function signature: fn(element, index) -> [variable]
-- @return New enum object with original elements replaced by fn's return values.
function enums:map(fn)
local t = {}
for i,v in ipairs(self.table) do
t[i] = fn(v)
end
return enum(t)
end
--- Reduces table or string to a single value.
-- Applies a function on each value of the table and accumulates
-- the return values of the function in a variable which is then returned.
-- @param fn Function that will be executed on each value.
-- Function signature: fn(
-- prev, -- The value returned by the most recent fn-call.
-- curr, -- value of the current table element
-- index, -- index of curr
-- )
-- @param init Initial value of the accumulator. 0 if no value given.
-- @return Single value that was built by calling fn on each element.
-- @see enums:fold
-- @see enums:inject
function enums:reduce(fn, init)
local acc = init or 0
for i,v in ipairs(self.table) do
acc = fn(acc,v,i)
end
return acc
end
--- @see enums:reduce
enums.fold = enums.reduce
--- @see enums:reduce
enums.inject = enums.reduce
--- Checks if a function returns true for all elements.
-- @param fn Callback function that takes a value (and an index)
-- and returns a boolean value.
-- @return `true` if fn returned `true` for all array elements. Otherwise false.
function enums:all(fn)
for i,v in ipairs(self.table) do
if fn(v,i) == false then
return false
end
end
return true
end
--- Checks if a function returns true for at least one element.
-- @param fn Callback function that takes a value (and an index)
-- and returns a boolean value.
-- @return `true` if fn returned `true` at least once. Otherwise false.
function enums:any(fn)
for i,v in ipairs(self.table) do
if fn(v,i) == true then
return true
end
end
return false
end
--- Counts elements for which fn returns `true`.
-- @param fn Callback function that takes a value (and an index)
-- and returns a boolean value.
-- @return Number of elements for which fn returned `true`
function enums:count(fn)
local c = 0
for i,v in ipairs(self.table) do
if fn(v,i) == true then
c = c+1
end
end
return c
end
return enum