@bitbybit-dev/base 0.19.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +71 -0
- package/babel.config.cjs +14 -0
- package/babel.config.d.cts +5 -0
- package/index.d.ts +1 -0
- package/index.js +4 -0
- package/lib/api/index.d.ts +1 -0
- package/lib/api/index.js +1 -0
- package/lib/api/inputs/base-inputs.d.ts +35 -0
- package/lib/api/inputs/base-inputs.js +1 -0
- package/lib/api/inputs/color-inputs.d.ts +122 -0
- package/lib/api/inputs/color-inputs.js +164 -0
- package/lib/api/inputs/index.d.ts +8 -0
- package/lib/api/inputs/index.js +8 -0
- package/lib/api/inputs/inputs.d.ts +10 -0
- package/lib/api/inputs/inputs.js +10 -0
- package/lib/api/inputs/lists-inputs.d.ts +478 -0
- package/lib/api/inputs/lists-inputs.js +576 -0
- package/lib/api/inputs/logic-inputs.d.ts +163 -0
- package/lib/api/inputs/logic-inputs.js +111 -0
- package/lib/api/inputs/math-inputs.d.ts +311 -0
- package/lib/api/inputs/math-inputs.js +391 -0
- package/lib/api/inputs/point-inputs.d.ts +446 -0
- package/lib/api/inputs/point-inputs.js +521 -0
- package/lib/api/inputs/text-inputs.d.ts +83 -0
- package/lib/api/inputs/text-inputs.js +120 -0
- package/lib/api/inputs/transforms-inputs.d.ts +136 -0
- package/lib/api/inputs/transforms-inputs.js +200 -0
- package/lib/api/inputs/vector-inputs.d.ts +300 -0
- package/lib/api/inputs/vector-inputs.js +304 -0
- package/lib/api/services/color.d.ts +114 -0
- package/lib/api/services/color.js +170 -0
- package/lib/api/services/geometry-helper.d.ts +15 -0
- package/lib/api/services/geometry-helper.js +151 -0
- package/lib/api/services/index.d.ts +9 -0
- package/lib/api/services/index.js +9 -0
- package/lib/api/services/lists.d.ts +287 -0
- package/lib/api/services/lists.js +682 -0
- package/lib/api/services/logic.d.ts +99 -0
- package/lib/api/services/logic.js +203 -0
- package/lib/api/services/math.d.ts +349 -0
- package/lib/api/services/math.js +621 -0
- package/lib/api/services/point.d.ts +223 -0
- package/lib/api/services/point.js +351 -0
- package/lib/api/services/text.d.ts +69 -0
- package/lib/api/services/text.js +84 -0
- package/lib/api/services/transforms.d.ts +122 -0
- package/lib/api/services/transforms.js +256 -0
- package/lib/api/services/vector.d.ts +320 -0
- package/lib/api/services/vector.js +468 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,682 @@
|
|
|
1
|
+
import * as Inputs from "../inputs/inputs";
|
|
2
|
+
/**
|
|
3
|
+
* Contains various list methods.
|
|
4
|
+
* <div>
|
|
5
|
+
* <img src="../assets/images/blockly-images/math/math.svg" alt="Blockly Image"/>
|
|
6
|
+
* </div>
|
|
7
|
+
*/
|
|
8
|
+
export class Lists {
|
|
9
|
+
/**
|
|
10
|
+
* Gets an item from the list by using a 0 based index
|
|
11
|
+
* @param inputs a list and an index
|
|
12
|
+
* @returns item
|
|
13
|
+
* @group get
|
|
14
|
+
* @shortname item by index
|
|
15
|
+
* @drawable false
|
|
16
|
+
*/
|
|
17
|
+
getItem(inputs) {
|
|
18
|
+
if (inputs.index < 0 || inputs.index >= inputs.list.length) {
|
|
19
|
+
throw new Error("Index out of bounds");
|
|
20
|
+
}
|
|
21
|
+
let result;
|
|
22
|
+
if (inputs.clone) {
|
|
23
|
+
result = structuredClone(inputs.list[inputs.index]);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
result = inputs.list[inputs.index];
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Gets items randomly by using a threshold
|
|
32
|
+
* @param inputs a list and a threshold for randomization of items to remove
|
|
33
|
+
* @returns list with remaining items
|
|
34
|
+
* @group get
|
|
35
|
+
* @shortname random get threshold
|
|
36
|
+
* @drawable false
|
|
37
|
+
*/
|
|
38
|
+
randomGetThreshold(inputs) {
|
|
39
|
+
let res = inputs.list;
|
|
40
|
+
if (inputs.clone) {
|
|
41
|
+
res = structuredClone(inputs.list);
|
|
42
|
+
}
|
|
43
|
+
const newList = [];
|
|
44
|
+
for (let i = 0; i < inputs.list.length; i++) {
|
|
45
|
+
if (Math.random() < inputs.threshold) {
|
|
46
|
+
newList.push(res[i]);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return newList;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Gets a sub list between start and end indexes
|
|
53
|
+
* @param inputs a list and start and end indexes
|
|
54
|
+
* @returns sub list
|
|
55
|
+
* @group get
|
|
56
|
+
* @shortname sublist
|
|
57
|
+
* @drawable false
|
|
58
|
+
*/
|
|
59
|
+
getSubList(inputs) {
|
|
60
|
+
let result;
|
|
61
|
+
if (inputs.clone) {
|
|
62
|
+
result = structuredClone(inputs.list.slice(inputs.indexStart, inputs.indexEnd));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
result = inputs.list.slice(inputs.indexStart, inputs.indexEnd);
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Gets nth item in the list
|
|
71
|
+
* @param inputs a list and index
|
|
72
|
+
* @returns list with filtered items
|
|
73
|
+
* @group get
|
|
74
|
+
* @shortname every n-th
|
|
75
|
+
* @drawable false
|
|
76
|
+
*/
|
|
77
|
+
getNthItem(inputs) {
|
|
78
|
+
let cloned = inputs.list;
|
|
79
|
+
if (inputs.clone) {
|
|
80
|
+
cloned = structuredClone(inputs.list);
|
|
81
|
+
}
|
|
82
|
+
const result = [];
|
|
83
|
+
for (let i = 0; i < cloned.length; i++) {
|
|
84
|
+
if ((i + inputs.offset) % inputs.nth === 0) {
|
|
85
|
+
result.push(cloned[i]);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Gets elements by pattern
|
|
92
|
+
* @param inputs a list and index
|
|
93
|
+
* @returns list with filtered items
|
|
94
|
+
* @group get
|
|
95
|
+
* @shortname by pattern
|
|
96
|
+
* @drawable false
|
|
97
|
+
*/
|
|
98
|
+
getByPattern(inputs) {
|
|
99
|
+
const { list, pattern } = inputs;
|
|
100
|
+
if (!pattern || pattern.length === 0) {
|
|
101
|
+
throw new Error("Pattern is empty or does not exist");
|
|
102
|
+
}
|
|
103
|
+
const patternLength = pattern.length;
|
|
104
|
+
const listLength = list.length;
|
|
105
|
+
const result = [];
|
|
106
|
+
if (patternLength >= listLength) {
|
|
107
|
+
list.forEach((item, index) => {
|
|
108
|
+
if (pattern[index] === true) {
|
|
109
|
+
result.push(item);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
const repeatedPattern = [];
|
|
115
|
+
const repeatPatternTimes = Math.ceil(listLength / patternLength);
|
|
116
|
+
for (let i = 0; i < repeatPatternTimes; i++) {
|
|
117
|
+
repeatedPattern.push(...pattern);
|
|
118
|
+
}
|
|
119
|
+
list.forEach((item, index) => {
|
|
120
|
+
if (repeatedPattern[index] === true) {
|
|
121
|
+
result.push(item);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Merge elements of lists on a given level and flatten output if needed
|
|
129
|
+
* @param inputs lists, level and flatten data
|
|
130
|
+
* @returns list with merged lists and flattened lists
|
|
131
|
+
* @group get
|
|
132
|
+
* @shortname merge levels
|
|
133
|
+
* @drawable false
|
|
134
|
+
*/
|
|
135
|
+
mergeElementsOfLists(inputs) {
|
|
136
|
+
const lists = inputs.lists;
|
|
137
|
+
const level = inputs.level;
|
|
138
|
+
const elToMerge = [];
|
|
139
|
+
const result = [];
|
|
140
|
+
lists.forEach(list => {
|
|
141
|
+
// flatten to certain level;
|
|
142
|
+
const elementsToMerge = list.flat(level);
|
|
143
|
+
elToMerge.push(elementsToMerge);
|
|
144
|
+
});
|
|
145
|
+
const lengthMerge = this.getLongestListLength({ lists: elToMerge });
|
|
146
|
+
for (let i = 0; i < lengthMerge; i++) {
|
|
147
|
+
const temp = [];
|
|
148
|
+
for (let j = 0; j < elToMerge.length; j++) {
|
|
149
|
+
const element = elToMerge[j][i];
|
|
150
|
+
if (element !== undefined) {
|
|
151
|
+
temp.push(element);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (temp.length > 0) {
|
|
155
|
+
result.push(temp);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
let final = [];
|
|
159
|
+
if (level > 0) {
|
|
160
|
+
for (let i = 0; i < level; i++) {
|
|
161
|
+
if (i === level - 1 && i !== 0) {
|
|
162
|
+
final[i - 1].push(result);
|
|
163
|
+
}
|
|
164
|
+
else if (i === level - 1) {
|
|
165
|
+
final.push(result);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
final.push([]);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
final = result;
|
|
174
|
+
}
|
|
175
|
+
return final;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Gets the longest list length from the list of lists
|
|
179
|
+
* @param inputs a list of lists
|
|
180
|
+
* @returns number of max length
|
|
181
|
+
* @group get
|
|
182
|
+
* @shortname longest list length
|
|
183
|
+
* @drawable false
|
|
184
|
+
*/
|
|
185
|
+
getLongestListLength(inputs) {
|
|
186
|
+
let longestSoFar = 0;
|
|
187
|
+
if (inputs.lists) {
|
|
188
|
+
inputs.lists.forEach(l => {
|
|
189
|
+
if (l.length > longestSoFar) {
|
|
190
|
+
longestSoFar = l.length;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
return longestSoFar;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Reverse the list
|
|
201
|
+
* @param inputs a list and an index
|
|
202
|
+
* @returns item
|
|
203
|
+
* @group edit
|
|
204
|
+
* @shortname reverse
|
|
205
|
+
* @drawable false
|
|
206
|
+
*/
|
|
207
|
+
reverse(inputs) {
|
|
208
|
+
let res = inputs.list;
|
|
209
|
+
if (inputs.clone) {
|
|
210
|
+
res = structuredClone(inputs.list);
|
|
211
|
+
}
|
|
212
|
+
return res.reverse();
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Flip 2d lists - every nth element of each list will form a separate list
|
|
216
|
+
* @param inputs a list of lists to flip
|
|
217
|
+
* @returns item
|
|
218
|
+
* @group edit
|
|
219
|
+
* @shortname flip lists
|
|
220
|
+
* @drawable false
|
|
221
|
+
*/
|
|
222
|
+
flipLists(inputs) {
|
|
223
|
+
if (inputs.list.length > 0) {
|
|
224
|
+
const lengthOfFirstList = inputs.list[0].length;
|
|
225
|
+
let allListsSameLength = true;
|
|
226
|
+
inputs.list.forEach(l => {
|
|
227
|
+
if (l.length !== lengthOfFirstList) {
|
|
228
|
+
allListsSameLength = false;
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
if (allListsSameLength) {
|
|
232
|
+
const result = [];
|
|
233
|
+
for (let i = 0; i < lengthOfFirstList; i++) {
|
|
234
|
+
const newList = [];
|
|
235
|
+
inputs.list.forEach(l => {
|
|
236
|
+
newList.push(l[i]);
|
|
237
|
+
});
|
|
238
|
+
result.push(newList);
|
|
239
|
+
}
|
|
240
|
+
return result;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
throw new Error("Lists are not of the same length");
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
throw new Error("List is empty");
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Group in lists of n elements
|
|
252
|
+
* @param inputs a list
|
|
253
|
+
* @returns items grouped in lists of n elements
|
|
254
|
+
* @group edit
|
|
255
|
+
* @shortname group elements
|
|
256
|
+
* @drawable false
|
|
257
|
+
*/
|
|
258
|
+
groupNth(inputs) {
|
|
259
|
+
const groupElements = (inputs) => {
|
|
260
|
+
const { nrElements, list, keepRemainder } = inputs;
|
|
261
|
+
const nrElementsInGroup = nrElements;
|
|
262
|
+
const result = [];
|
|
263
|
+
let currentGroup = [];
|
|
264
|
+
list.forEach((item, index) => {
|
|
265
|
+
currentGroup.push(item);
|
|
266
|
+
if ((index + 1) % nrElementsInGroup === 0) {
|
|
267
|
+
result.push(currentGroup);
|
|
268
|
+
currentGroup = [];
|
|
269
|
+
}
|
|
270
|
+
if (keepRemainder && index === list.length - 1) {
|
|
271
|
+
result.push(currentGroup);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
return result;
|
|
275
|
+
};
|
|
276
|
+
// TODO make this work on any level
|
|
277
|
+
return groupElements(inputs);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Get the depth of the list
|
|
281
|
+
* @param inputs a list
|
|
282
|
+
* @returns number of depth
|
|
283
|
+
* @group get
|
|
284
|
+
* @shortname max list depth
|
|
285
|
+
* @drawable false
|
|
286
|
+
*/
|
|
287
|
+
getListDepth(inputs) {
|
|
288
|
+
let levels = 0;
|
|
289
|
+
let deeperLevelsExist = true;
|
|
290
|
+
let flatRes = inputs.list;
|
|
291
|
+
while (deeperLevelsExist) {
|
|
292
|
+
let foundArray = false;
|
|
293
|
+
for (let i = 0; i < flatRes.length; i++) {
|
|
294
|
+
if (Array.isArray(flatRes[i])) {
|
|
295
|
+
foundArray = true;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
flatRes = flatRes.flat();
|
|
299
|
+
if (foundArray) {
|
|
300
|
+
levels++;
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
levels++;
|
|
304
|
+
deeperLevelsExist = false;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return levels;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Gets the length of the list
|
|
311
|
+
* @param inputs a length list
|
|
312
|
+
* @returns a number
|
|
313
|
+
* @group get
|
|
314
|
+
* @shortname list length
|
|
315
|
+
* @drawable false
|
|
316
|
+
*/
|
|
317
|
+
listLength(inputs) {
|
|
318
|
+
return inputs.list.length;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Add item to the list
|
|
322
|
+
* @param inputs a list, item and an index
|
|
323
|
+
* @returns list with added item
|
|
324
|
+
* @group add
|
|
325
|
+
* @shortname add item
|
|
326
|
+
* @drawable false
|
|
327
|
+
*/
|
|
328
|
+
addItemAtIndex(inputs) {
|
|
329
|
+
let res = inputs.list;
|
|
330
|
+
if (inputs.clone) {
|
|
331
|
+
res = structuredClone(inputs.list);
|
|
332
|
+
}
|
|
333
|
+
if (inputs.index >= 0 && inputs.index <= res.length) {
|
|
334
|
+
res.splice(inputs.index, 0, inputs.item);
|
|
335
|
+
}
|
|
336
|
+
return res;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Adds item to the list of provided indexes
|
|
340
|
+
* @param inputs a list, item and an indexes
|
|
341
|
+
* @returns list with added item
|
|
342
|
+
* @group add
|
|
343
|
+
* @shortname add item at indexes
|
|
344
|
+
* @drawable false
|
|
345
|
+
*/
|
|
346
|
+
addItemAtIndexes(inputs) {
|
|
347
|
+
let cloned = inputs.list;
|
|
348
|
+
if (inputs.clone) {
|
|
349
|
+
cloned = structuredClone(inputs.list);
|
|
350
|
+
}
|
|
351
|
+
let cloneIndexes = [...inputs.indexes];
|
|
352
|
+
cloneIndexes = cloneIndexes.filter(index => index >= 0 && index <= cloned.length);
|
|
353
|
+
cloneIndexes.sort((a, b) => a - b);
|
|
354
|
+
cloneIndexes.forEach((index, i) => {
|
|
355
|
+
if (index >= 0 && index + i <= cloned.length) {
|
|
356
|
+
cloned.splice(index + i, 0, inputs.item);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
return cloned;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Adds items to the list of provided indexes matching 1:1, first item will go to first index provided, etc.
|
|
363
|
+
* @param inputs a list, items and an indexes
|
|
364
|
+
* @returns list with added items
|
|
365
|
+
* @group add
|
|
366
|
+
* @shortname add items
|
|
367
|
+
* @drawable false
|
|
368
|
+
*/
|
|
369
|
+
addItemsAtIndexes(inputs) {
|
|
370
|
+
if (inputs.items.length !== inputs.indexes.length) {
|
|
371
|
+
throw new Error("Items and indexes must have the same length");
|
|
372
|
+
}
|
|
373
|
+
for (let i = 0; i < inputs.indexes.length; i++) {
|
|
374
|
+
if (i > 0) {
|
|
375
|
+
const prev = inputs.indexes[i - 1];
|
|
376
|
+
if (prev > inputs.indexes[i]) {
|
|
377
|
+
throw new Error("Indexes must be in ascending order");
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
let cloned = inputs.list;
|
|
382
|
+
if (inputs.clone) {
|
|
383
|
+
cloned = structuredClone(inputs.list);
|
|
384
|
+
}
|
|
385
|
+
const cloneIndexes = [...inputs.indexes];
|
|
386
|
+
cloneIndexes.forEach((index, i) => {
|
|
387
|
+
if (index >= 0 && index + i <= cloned.length) {
|
|
388
|
+
cloned.splice(index + i, 0, inputs.items[i]);
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
return cloned;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Remove item from the list
|
|
395
|
+
* @param inputs a list and index
|
|
396
|
+
* @returns list with removed item
|
|
397
|
+
* @group remove
|
|
398
|
+
* @shortname remove item
|
|
399
|
+
* @drawable false
|
|
400
|
+
*/
|
|
401
|
+
removeItemAtIndex(inputs) {
|
|
402
|
+
let res = inputs.list;
|
|
403
|
+
if (inputs.clone) {
|
|
404
|
+
res = structuredClone(inputs.list);
|
|
405
|
+
}
|
|
406
|
+
if (inputs.index >= 0 && inputs.index <= res.length) {
|
|
407
|
+
res.splice(inputs.index, 1);
|
|
408
|
+
}
|
|
409
|
+
return res;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Remove items from the list of provided indexes
|
|
413
|
+
* @param inputs a list and indexes
|
|
414
|
+
* @returns list with removed items
|
|
415
|
+
* @group remove
|
|
416
|
+
* @shortname remove items
|
|
417
|
+
* @drawable false
|
|
418
|
+
*/
|
|
419
|
+
removeItemsAtIndexes(inputs) {
|
|
420
|
+
let res = inputs.list;
|
|
421
|
+
if (inputs.clone) {
|
|
422
|
+
res = structuredClone(inputs.list);
|
|
423
|
+
}
|
|
424
|
+
const cloneIndexes = [...inputs.indexes];
|
|
425
|
+
cloneIndexes.sort((a, b) => b - a);
|
|
426
|
+
cloneIndexes.forEach(index => {
|
|
427
|
+
if (index >= 0 && index < res.length) {
|
|
428
|
+
res.splice(index, 1);
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
return res;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Remove all items from the list
|
|
435
|
+
* @param inputs a list
|
|
436
|
+
* @returns The length is set to 0 and same array memory object is returned
|
|
437
|
+
* @group remove
|
|
438
|
+
* @shortname remove all items
|
|
439
|
+
* @drawable false
|
|
440
|
+
*/
|
|
441
|
+
removeAllItems(inputs) {
|
|
442
|
+
inputs.list.length = 0;
|
|
443
|
+
return inputs.list;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Remove item from the list
|
|
447
|
+
* @param inputs a list and index
|
|
448
|
+
* @returns list with removed item
|
|
449
|
+
* @group remove
|
|
450
|
+
* @shortname every n-th
|
|
451
|
+
* @drawable false
|
|
452
|
+
*/
|
|
453
|
+
removeNthItem(inputs) {
|
|
454
|
+
let res = inputs.list;
|
|
455
|
+
if (inputs.clone) {
|
|
456
|
+
res = structuredClone(inputs.list);
|
|
457
|
+
}
|
|
458
|
+
const result = [];
|
|
459
|
+
for (let i = 0; i < res.length; i++) {
|
|
460
|
+
if ((i + inputs.offset) % inputs.nth !== 0) {
|
|
461
|
+
result.push(res[i]);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return result;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Removes items randomly by using a threshold
|
|
468
|
+
* @param inputs a list and a threshold for randomization of items to remove
|
|
469
|
+
* @returns list with removed items
|
|
470
|
+
* @group remove
|
|
471
|
+
* @shortname random remove threshold
|
|
472
|
+
* @drawable false
|
|
473
|
+
*/
|
|
474
|
+
randomRemoveThreshold(inputs) {
|
|
475
|
+
let res = inputs.list;
|
|
476
|
+
if (inputs.clone) {
|
|
477
|
+
res = structuredClone(inputs.list);
|
|
478
|
+
}
|
|
479
|
+
const newList = [];
|
|
480
|
+
for (let i = 0; i < inputs.list.length; i++) {
|
|
481
|
+
if (Math.random() > inputs.threshold) {
|
|
482
|
+
newList.push(res[i]);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return newList;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* remove duplicate numbers from the list
|
|
489
|
+
* @param inputs a list of numbers
|
|
490
|
+
* @returns list with unique numbers
|
|
491
|
+
* @group remove
|
|
492
|
+
* @shortname remove duplicates
|
|
493
|
+
* @drawable false
|
|
494
|
+
*/
|
|
495
|
+
removeDuplicateNumbers(inputs) {
|
|
496
|
+
let res = inputs.list;
|
|
497
|
+
if (inputs.clone) {
|
|
498
|
+
res = structuredClone(inputs.list);
|
|
499
|
+
}
|
|
500
|
+
return res.filter((value, index, self) => self.indexOf(value) === index);
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* remove duplicate numbers from the list with tolerance
|
|
504
|
+
* @param inputs a list of numbers and the tolerance
|
|
505
|
+
* @returns list with unique numbers
|
|
506
|
+
* @group remove
|
|
507
|
+
* @shortname remove duplicates tol
|
|
508
|
+
* @drawable false
|
|
509
|
+
*/
|
|
510
|
+
removeDuplicateNumbersTolerance(inputs) {
|
|
511
|
+
let res = inputs.list;
|
|
512
|
+
if (inputs.clone) {
|
|
513
|
+
res = structuredClone(inputs.list);
|
|
514
|
+
}
|
|
515
|
+
return res.filter((value, index, self) => self.findIndex(s => Math.abs(s - value) < inputs.tolerance) === index);
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Add item to the end of the list
|
|
519
|
+
* @param inputs a list and an item
|
|
520
|
+
* @returns list with added item
|
|
521
|
+
* @group add
|
|
522
|
+
* @shortname add item to list
|
|
523
|
+
* @drawable false
|
|
524
|
+
*/
|
|
525
|
+
addItem(inputs) {
|
|
526
|
+
let res = inputs.list;
|
|
527
|
+
if (inputs.clone) {
|
|
528
|
+
res = structuredClone(inputs.list);
|
|
529
|
+
}
|
|
530
|
+
res.push(inputs.item);
|
|
531
|
+
return res;
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Add item to the beginning of the list
|
|
535
|
+
* @param inputs a list and an item
|
|
536
|
+
* @returns list with added item
|
|
537
|
+
* @group add
|
|
538
|
+
* @shortname prepend item to list
|
|
539
|
+
* @drawable false
|
|
540
|
+
*/
|
|
541
|
+
prependItem(inputs) {
|
|
542
|
+
let res = inputs.list;
|
|
543
|
+
if (inputs.clone) {
|
|
544
|
+
res = structuredClone(inputs.list);
|
|
545
|
+
}
|
|
546
|
+
res.unshift(inputs.item);
|
|
547
|
+
return res;
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Add item to the beginning or the end of the list
|
|
551
|
+
* @param inputs a list, item and an option for first or last position
|
|
552
|
+
* @returns list with added item
|
|
553
|
+
* @group add
|
|
554
|
+
* @shortname item at first or last
|
|
555
|
+
* @drawable false
|
|
556
|
+
*/
|
|
557
|
+
addItemFirstLast(inputs) {
|
|
558
|
+
let res = inputs.list;
|
|
559
|
+
if (inputs.clone) {
|
|
560
|
+
res = structuredClone(inputs.list);
|
|
561
|
+
}
|
|
562
|
+
if (inputs.position === Inputs.Lists.firstLastEnum.first) {
|
|
563
|
+
res.unshift(inputs.item);
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
res.push(inputs.item);
|
|
567
|
+
}
|
|
568
|
+
return res;
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Creates an empty list
|
|
572
|
+
* @returns an empty array list
|
|
573
|
+
* @group create
|
|
574
|
+
* @shortname empty list
|
|
575
|
+
* @drawable false
|
|
576
|
+
*/
|
|
577
|
+
createEmptyList() {
|
|
578
|
+
return [];
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Repeat the item and add it in the new list
|
|
582
|
+
* @param inputs an item to multiply
|
|
583
|
+
* @returns list
|
|
584
|
+
* @group create
|
|
585
|
+
* @shortname repeat
|
|
586
|
+
* @drawable false
|
|
587
|
+
*/
|
|
588
|
+
repeat(inputs) {
|
|
589
|
+
const result = [];
|
|
590
|
+
for (let i = 0; i < inputs.times; i++) {
|
|
591
|
+
result.push(inputs.item);
|
|
592
|
+
}
|
|
593
|
+
return result;
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Repeat the list items by adding them in the new list till the certain length of the list is reached
|
|
597
|
+
* @param inputs a list to multiply and a length limit
|
|
598
|
+
* @returns list
|
|
599
|
+
* @group create
|
|
600
|
+
* @shortname repeat in pattern
|
|
601
|
+
* @drawable false
|
|
602
|
+
*/
|
|
603
|
+
repeatInPattern(inputs) {
|
|
604
|
+
// will repeat the items provided in the patten till the certain length of the list is reached
|
|
605
|
+
let inpList = inputs.list;
|
|
606
|
+
if (inputs.clone) {
|
|
607
|
+
inpList = structuredClone(inputs.list);
|
|
608
|
+
}
|
|
609
|
+
const res = [];
|
|
610
|
+
let counter = 0;
|
|
611
|
+
let index = 0;
|
|
612
|
+
while (counter < inputs.lengthLimit) {
|
|
613
|
+
res.push(inpList[index]);
|
|
614
|
+
index++;
|
|
615
|
+
if (index === inpList.length) {
|
|
616
|
+
index = 0;
|
|
617
|
+
}
|
|
618
|
+
counter++;
|
|
619
|
+
}
|
|
620
|
+
return res;
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Sort the list of numbers in ascending or descending order
|
|
624
|
+
* @param inputs a list of numbers to sort and an option for ascending or descending order
|
|
625
|
+
* @returns list
|
|
626
|
+
* @group sorting
|
|
627
|
+
* @shortname sort numbers
|
|
628
|
+
* @drawable false
|
|
629
|
+
*/
|
|
630
|
+
sortNumber(inputs) {
|
|
631
|
+
let res = inputs.list;
|
|
632
|
+
if (inputs.clone) {
|
|
633
|
+
res = structuredClone(inputs.list);
|
|
634
|
+
}
|
|
635
|
+
if (inputs.orderAsc) {
|
|
636
|
+
return res.sort((a, b) => a - b);
|
|
637
|
+
}
|
|
638
|
+
else {
|
|
639
|
+
return res.sort((a, b) => b - a);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Sort the list of texts in ascending or descending order alphabetically
|
|
644
|
+
* @param inputs a list of texts to sort and an option for ascending or descending order
|
|
645
|
+
* @returns list
|
|
646
|
+
* @group sorting
|
|
647
|
+
* @shortname sort texts
|
|
648
|
+
* @drawable false
|
|
649
|
+
*/
|
|
650
|
+
sortTexts(inputs) {
|
|
651
|
+
let res = inputs.list;
|
|
652
|
+
if (inputs.clone) {
|
|
653
|
+
res = structuredClone(inputs.list);
|
|
654
|
+
}
|
|
655
|
+
if (inputs.orderAsc) {
|
|
656
|
+
return res.sort();
|
|
657
|
+
}
|
|
658
|
+
else {
|
|
659
|
+
return res.sort().reverse();
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Sort by numeric JSON property value
|
|
664
|
+
* @param inputs a list to sort, a property to sort by and an option for ascending or descending order
|
|
665
|
+
* @returns list
|
|
666
|
+
* @group sorting
|
|
667
|
+
* @shortname sort json objects
|
|
668
|
+
* @drawable false
|
|
669
|
+
*/
|
|
670
|
+
sortByPropValue(inputs) {
|
|
671
|
+
let res = inputs.list;
|
|
672
|
+
if (inputs.clone) {
|
|
673
|
+
res = structuredClone(inputs.list);
|
|
674
|
+
}
|
|
675
|
+
if (inputs.orderAsc) {
|
|
676
|
+
return res.sort((a, b) => a[inputs.property] - b[inputs.property]);
|
|
677
|
+
}
|
|
678
|
+
else {
|
|
679
|
+
return res.sort((a, b) => b[inputs.property] - a[inputs.property]);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|