-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patht-util.lua
More file actions
347 lines (302 loc) · 9.48 KB
/
Copy patht-util.lua
File metadata and controls
347 lines (302 loc) · 9.48 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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
-- t-util for Lua 5.1 by Loominatrx
-- Compatible with Luau and Vanilla Lua.
-- Lua's table references
local sort = table.sort
local insert, remove, move = table.insert, table.remove, table.move
local pack, unpack, concat = table.pack, table.unpack, table.concat
local random = math.random
local foreach, foreachi = table.foreach, table.foreachi
-- Luau's table references
local tfind = table.find
local getn, create = table.getn, table.create
local clear = table.clear
-- New table
local table = {}
-- Private methods
local function tableCheck(v)
return type(v) == 'table'
end
-- Public Methods
-- Returns the total number of the element in a table.
function table.count(tbl)
local n = 0
for _ in pairs(tbl) do
n = n + 1
end
return n
end
-- Returns the total number of the element in a table recursively.
function table.deepCount(tbl)
local n = 0
for _, v in pairs(tbl) do
n = type(v) == 'table' and n + table.deepCount(v) or n + 1
end
return n
end
-- Determines whether the table contains a value, returning `true` or `false` as appropriate.
function table.includes(tbl, value)
for _, v in next, tbl do
if v == value then return true end
end
return false
end
-- Determines if the `tbl` has `index` on it, returning `true` or `false` as appropriate.
function table.has(tbl, index)
return tbl[index] ~= nil
end
-- Determines if the table is empty. Returns `true` or `false`, as appropriate.
function table.isEmpty(tbl)
return next(tbl) == nil
end
-- Determines if the table is a array-like table.
function table.isArray(tbl)
-- Make sure it's not empty.
if table.isEmpty(tbl) then
return false
end
-- Make sure that all keys are positive integers
for key, value in pairs(tbl) do
if type(key) ~= 'number' or key % 1 ~= 0 or key < 1 then
return false
end
end
return true
end
-- Determines if the table is a dictionary-like table.
-- A dictionary is defined as a table containing keys that are not positive integers.
function table.isDictionary(tbl)
return not table.isArray(tbl)
end
-- Returns a new copy of the table, one layer deep.
function table.copy(tbl)
local ret = {}
for k, v in pairs(tbl) do
ret[k] = v
end
return ret
end
--[[
Returns a copy of table, recursively.
If a table is encountered, it is recursively deep-copied.
Metatables are not copied.
]]
function table.deepCopy(tbl)
local ret = {}
for k, v in pairs(tbl) do
ret[k] = type(v) == 'table' and table.deepCopy(v) or v
end
return ret
end
-- Reverses the element of an array-like table in place.
function table.reverse(tbl)
if table.isEmpty(tbl) then
error('`tbl` must not be empty!', 2)
elseif table.isDictionary(tbl) then
error('`tbl` must be a array-like table!', 2)
end
for i = 1, #tbl do
insert(tbl, i, remove(tbl))
end
end
-- Returns a copy of an array-like table with its element in reverse order.
-- The original table remain unchanged.
function table.reversed(tbl)
if table.isEmpty(tbl) then
error('`tbl` must not be empty!', 2)
elseif table.isDictionary(tbl) then
error('`tbl` must be a array-like table!', 2)
end
local ret = {}
for i = #tbl, 1, -1 do
insert(ret, tbl[i])
end
return ret
end
-- Returns a new array-like table where all of its values are the keys of the original table.
function table.keys(tbl)
local ret = {}
for k in pairs(tbl) do
insert(ret, k)
end
return ret
end
-- Returns a new array-like table where all of its values are the values of the original table.
function table.values(tbl)
local ret = {}
for _, v in pairs(tbl) do
insert(ret, v)
end
return ret
end
-- Returns a random (index, value) pair from an array-like table.
function table.randomIpair(tbl)
local i = random(#tbl)
return i, tbl[i]
end
-- Returns a random (key, value) pair from a dictionary-like table.
function table.randomPair(tbl)
local rand = random(table.count(tbl))
local n = 0
for k, v in pairs(tbl) do
n = n + 1
if n == rand then
return k, v
end
end
end
-- Returns a copy of an array-like table sorted using Lua's `table.sort`.
function table.sorted(tbl, fn)
local ret = {}
for i, v in ipairs(tbl) do
ret[i] = v
end
sort(ret, fn)
return ret
end
-- Returns a new table that is a slice of the original, defined by the start and stop bounds and the step size.
-- Default start, stop, and step values are 1, #tbl, and 1 respectively.
function table.slice(tbl, start, stop, step)
local ret = {}
for i = start or 1, stop or #tbl, step or 1 do
insert(ret, tbl[i])
end
return ret
end
-- Iterates through a table until a value satisfies the test function.
-- The `value` is returned if it satisfies the test function. Otherwise, `nil` is returned.
function table.findValue(tbl, testFn)
for key, value in pairs(tbl) do
if testFn(value, key) == true then
return value
end
end
return nil
end
-- Iterates through a table until a key satisfies the test function.
-- The `key` is returned if it satisfies the test function. Otherwise, `nil` is returned.
function table.findIndex(tbl, testFn)
for key, value in pairs(tbl) do
if testFn(value, key) == true then
return key
end
end
return nil
end
-- Returns a new table containing all elements of the calling table
-- for which provided filtering function returns `true`.
function table.filter(tbl, filterFn)
local ret = {}
for key, value in pairs(tbl) do
if filterFn(value, key) then
ret[key] = value
end
end
return ret
end
-- Returns a new table containing the results of calling a function
-- on every element in this table.
function table.map(tbl, mapFn)
local ret = {}
for key, value in pairs(tbl) do
ret[key] = mapFn(value, key)
end
return ret
end
-- Iterates through the table and run the test function to to every element to check if it satisfies the check.
-- If all elements satisfies the check, it returns `true`. Otherwise it returns `false`.
function table.every(tbl, testFn)
for key, value in pairs(tbl) do
if testFn(value, key) == false then
return false
end
end
return true
end
-- Returns a new table that is this table joined with other table(s).
function table.merge(...)
local ret = {}
local tables = {...}
if not table.every(tables, tableCheck) then
error('`...table` must be a table!', 2)
end
for _, t in pairs(tables) do
for k, v in pairs(t) do
if type(k) == 'number' then
insert(ret, v)
else
ret[k] = v
end
end
end
return ret
end
-- Changes all elements in an array-like table to a static value
-- from start index (default: `1`) to an end index (default: `#tbl`).
-- It returns the modified array-like table.
function table.fill(tbl, value, start, End)
if table.isEmpty(tbl) then
error('`tbl` must not be empty!', 2)
elseif table.isDictionary(tbl) then
error('`tbl` must be a array-like table!', 2)
elseif start ~= nil and start <= 0 then
error('`start` must be more than 0!', 2)
elseif End ~= nil and End > #tbl then
error('`End` must not exceed #tbl!', 2)
end
for i = start or 1, End or #tbl do
tbl[i] = value
end
return tbl
end
-- Returns a new copy of the original array-like table and removes duplicate elements that exists on that table.
function table.removeDupes(tbl)
if table.isEmpty(tbl) then
error('`tbl` must not be empty!', 2)
elseif table.isDictionary(tbl) then
error('`tbl` must be a array-like table!', 2)
end
local hash = {}
local ret = {}
for _,v in ipairs(tbl) do
if not hash[v] then
insert(ret, v)
hash[v] = true
end
end
return ret
end
-- I don't wrap the methods using metatable, as Roblox don't let us wrap built-in objects
-- and the table object (in Luau) is read-only, meaning we can't add/modify functions on it.
if _VERSION ~= 'Luau' then
return setmetatable(_G.table, {
__index = table,
__tostring = function ()
return 't-util by Loominatrx'
end
})
else
-- Had to reference all of the built-ins due to Roblox's restrictions.
table.insert = insert
table.remove = remove
table.sort = sort
table.pack = pack
table.unpack = unpack
table.move = move
table.getn = getn -- deprecated in Lua 5.1, dunno why did they brought it to Luau.
-- but I reference it anyways for those who still uses `table.getn()` in 2021 (lol).
table.foreach = foreach
table.foreachi = foreachi
table.concat = concat
table.clear = clear
table.create = create
table.find = tfind
return setmetatable(table, {
__newindex = function()
error('Attempting to modify this object.', 2)
end,
__metatable = 'This metatable is locked.',
__tostring = function()
return 't-util by Loominatrx'
end
})
end