-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patharray.nut
444 lines (394 loc) · 10.9 KB
/
array.nut
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
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
/*
* Enhanced arrays module.
*/
::ArrayEx <- class {
// The internal array.
arr = null
length = 0;
// The internal table representation.
table = null;
tableIsValid = false;
/*
* Constructor for ArrayEx.
*
* Creates a new ArrayEx object from a variable number of arguments.
*
* @param {...} ... - A variable number of arguments representing the initial elements of the array.
*/
constructor(...) {
this.arr = array(vargc);
this.table = {};
for(local i = 0; i < vargc; i++) {
this.arr[i] = vargv[i]
}
}
/*
* Creates a new ArrayEx object from an existing array.
*
* If the input array is already an ArrayEx object, it is returned directly.
*
* @param {array} array - The initial array to use for the ArrayEx object.
* @returns {ArrayEx} - The newly created or the input ArrayEx object.
*/
function FromArray(array) {
if(typeof array == "ArrayEx") // dumb-ass protection :P
return array
local arrayEx = ArrayEx()
arrayEx.arr = array
return arrayEx
}
/*
* Creates a new ArrayEx object with a specified size, optionally filled with a default value.
*
* @param {int} numberOfItems - The desired number of elements in the array.
* @param {any} fillValue - The value to fill the array with (defaults to null).
* @returns {ArrayEx} - The newly created ArrayEx object.
*/
function WithSize(numberOfItems, fillValue = null) {
return ArrayEx.FromArray(array(numberOfItems, fillValue))
}
/*
* Append a value to the array.
*
* @param {any} val - The value to append.
* @returns {ArrayEx} - The ArrayEx instance for chaining.
*/
function append(val) {
this._pushToTable(val)
arr.append(val);
return this
}
/*
* Apply a function to each element and modify the array in-place.
*
* @param {Function} func - The function to apply.
* @returns {ArrayEx} - The ArrayEx instance for chaining.
*/
function apply(func) {
foreach(idx, value in arr) {
arr[idx] = func(value)
}
this.totable(true)
return this
}
/*
* Clear the array and table.
*
* @returns {ArrayEx} - The ArrayEx instance for chaining.
*/
function clear() {
this.arr.clear()
this.table.clear()
this.tableIsValid = false
return this
}
/*
* Extend the array with another array.
*
* @param {array|ArrayEx} other - The array to extend from.
* @returns {ArrayEx} - The ArrayEx instance for chaining.
*/
function extend(other) {
if(typeof other == "ArrayEx") {
other = other.arr
}
arr.extend(other);
this.totable(true)
return this
}
/*
* Filter the array by a predicate function.
*
* @param {Function} condition(index, value, newArray) - The predicate function.
* @returns {ArrayEx} - The filtered array.
*/
function filter(condition) {
local newArray = ArrayEx()
foreach(idx, val in arr) {
if(condition(idx, val, newArray))
newArray.append(val)
}
return newArray
}
/*
* Check if the array contains a value.
*
* @param {any} match - The value to find.
* @returns {boolean} - Whether the value is found.
*/
function contains(match) {
if(!this.tableIsValid) this.totable()
return match in this.table
}
/*
* Search for a value in the array.
*
* @param {any|Function} match - The value or predicate to search for.
* @returns {int|null} - The index of the match or null.
*/
function search(match) {
if(typeof match == "function") {
foreach(idx, val in arr) {
if(match(val))
return idx
}
}
else {
foreach(idx, val in arr) {
if(val == match)
return idx
}
}
return null
}
/*
* Insert a value into the array.
*
* @param {int} idx - The index to insert at.
* @param {any} val - The value to insert.
*/
function insert(idx, val) {
this._pushToTable(val)
return arr.insert(idx, val)
}
/*
* Get the array length.
*
* @returns {int} - The array length.
*/
function len() {
return this.arr.len()
}
/*
* Map the array to a new array via a function.
*
* @param {Function} func - The mapping function.
* @returns {ArrayEx} - The mapped array.
*/
function map(func) {
local newArray = array(this.len())
foreach(idx, value in arr) {
newArray[idx] = func(value)
}
return ArrayEx.FromArray(newArray)
}
/*
* Reduce the array to a single value.
*
* @param {Function} func - The reducer function, which takes the accumulator and current item as arguments.
* @param {any} initial - The initial value of the accumulator.
* @returns {any} - The reduced value.
*/
function reduce(func, initial) {
local accumulator = initial
foreach(item in arr) {
accumulator = func(accumulator, item)
}
return accumulator
}
/*
* Return a new array with only unique elements.
*
* @returns {ArrayEx} - The new array with unique elements.
*/
function unique() {
local seen = {}
local result = ArrayEx()
foreach(value in this.arr) {
if(value in seen) continue
seen[value] <- true
result.append(value)
}
return result
}
/*
* Pop a value off the end of the array.
*
* @returns {any} - The popped value.
*/
function pop() {
local pop = arr.pop()
this._deleteFromTable(pop)
return pop
}
/*
* Append a value to the array.
*
* @param {any} val - The value to append.
*/
function push(val) {
this.append(val)
}
/*
* Remove an element by index.
*
* @param {int} idx - The index to remove.
* @returns {any} - The value of the removed element.
*/
function remove(idx) {
local value = arr[idx]
this._deleteFromTable(arr[idx])
arr.remove(idx);
return value
}
/*
* Resize the array.
*
* @param {int} size - The new size.
* @param {any} fill - The fill value for new slots.
*/
function resize(size, fill = null) {
arr.resize(size, fill);
this.totable(true)
}
/*
* Reverse the array in-place.
*
* @returns {ArrayEx} - The reversed array.
*/
function reverse() {
arr.reverse();
return this
}
/*
* Slice a portion of the array.
*
* @param {int} startIndex - The start index.
* @param {int} endIndex - The end index. (optional)
* @returns {ArrayEx} - The sliced array.
*/
function slice(startIndex, endIndex = null) {
return ArrayEx.FromArray(arr.slice(startIndex, endIndex || this.len()))
}
/*
* Sort the array.
*
* @param {Function} func - Optional compare function.
* @returns {ArrayEx} - The sorted array.
*/
function sort(func = null) {
func ? arr.sort(func) : arr.sort()
return this
}
/*
* Get the last element.
*
* @returns {any} - The last element.
*/
function top() {
return arr.top();
}
/*
* Join the array into a string.
*
* @param {string} joinstr - The separator string.
* @returns {string} - The joined string.
*/
function join(joinstr = "") {
if(this.len() == 0) return ""
local string = ""
foreach(elem in this.arr) {
string += elem + joinstr
}
return joinstr.len() != 0 ? string.slice(0, joinstr.len() * -1) : string
}
/*
* Retrieve the element at the specified index in the array.
*
* @param {integer} idx - The index of the element to retrieve.
* @param {any} defaultVal - Optional default value to return if the index is out of bounds. Defaults to null.
* @returns {any} - The element at the specified index or the default value if the index is out of bounds.
*/
function get(idx, defaultVal = null) {
if(this.len() > idx)
return this.arr[idx]
return defaultVal
}
/*
* Convert the array to a table.
*
* @param {boolean} reacreate - Whether to recreate the table.
* @returns {table} - The table representation.
*/
function totable(reacreate = false) {
if(this.table.len() > 0 && !reacreate) return this.table
tableIsValid = true
this.table.clear()
foreach(element in arr) {
if(element) this.table[element] <- null
}
return this.table
}
function tolist() {
local list = List()
foreach(idx, value in this.arr) {
list.append(value)
}
return list
}
/*
* Delete a value from the internal table.
*
* @param {any} val - The value to delete.
*/
function _deleteFromTable(val) {
if(val in this.table)
this.table.rawdelete(val)
}
/*
* Add a value to the internal table.
*
* @param {any} val - The value to add.
*/
function _pushToTable(val) {
if(this.table.len() != 0)
this.table[val] <- null
}
function _cloned() {
return ArrayEx.FromArray(clone this.arr)
}
/*
* Convert the array to a string.
*
* @returns {string} - The string representation.
*/
function _tostring() return format("Array: [%s]", this.join(", "))
/*
* Get the type name.
*
* @returns {"ArrayEx"}
*/
function _typeof () return "ArrayEx";
/*
* Get an element by index.
*
* @param {int} idx - The index.
* @returns {any} - The element.
*/
function _get(idx) return arr[idx];
/*
* Set an element by index.
*
* @param {int} idx - The index.
* @param {any} val - The new value.
*/
function _set(idx, val) return arr[idx] = val;
function _nexti(previdx) {
if(this.len() == 0) return null
if (previdx == null) return 0;
return previdx < this.len() - 1 ? previdx + 1 : null;
}
function cmp(other) { // lmao, why? :O
local thisSum = 0;
local otherSum = 0;
foreach (val in this) { thisSum += val; }
foreach (val in other) { otherSum += val; }
if (thisSum > otherSum) {
return 1;
} else if (thisSum < otherSum) {
return -1;
} else {
return 0;
}
}
}