@kizmann/pico-js 1.0.13 → 2.0.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.
Files changed (125) hide show
  1. package/README.md +27 -7
  2. package/dist/pico-js.browser.js +2 -0
  3. package/dist/pico-js.browser.js.map +1 -0
  4. package/dist/pico-js.esm.js +2 -0
  5. package/dist/pico-js.esm.js.map +1 -0
  6. package/package.json +20 -7
  7. package/src/dom/DomAttribute.js +374 -0
  8. package/src/dom/DomBuilder.js +152 -0
  9. package/src/dom/DomEvent.js +253 -0
  10. package/src/dom/DomFinder.js +669 -0
  11. package/src/dom/DomForm.js +57 -0
  12. package/src/dom/DomGlobal.js +193 -0
  13. package/src/dom/DomInview.js +332 -0
  14. package/src/dom/DomMeta.js +66 -0
  15. package/src/dom/DomObserver.js +57 -0
  16. package/src/dom/DomRectangle.js +657 -0
  17. package/src/format/FormatFile.js +54 -0
  18. package/src/format/FormatOption.js +108 -0
  19. package/src/format/FormatParam.js +107 -0
  20. package/src/format/FormatParser.js +156 -0
  21. package/src/format/FormatUrl.js +75 -0
  22. package/src/index.browser.js +10 -0
  23. package/src/index.esm.js +138 -0
  24. package/src/now/NowDefault.js +533 -0
  25. package/src/now/NowFormat.js +196 -0
  26. package/src/now/NowGrid.js +251 -0
  27. package/src/now/NowHuman.js +118 -0
  28. package/src/now/NowMatch.js +175 -0
  29. package/src/now/NowRange.js +70 -0
  30. package/src/now/NowWalker.js +544 -0
  31. package/src/tool/scope.js +103 -0
  32. package/src/utils/Array.js +986 -0
  33. package/src/utils/Cookie.js +184 -0
  34. package/src/utils/Data.js +200 -0
  35. package/src/utils/Dom.js +208 -0
  36. package/src/utils/Event.js +140 -0
  37. package/src/utils/Format.js +62 -0
  38. package/src/utils/Hash.js +164 -0
  39. package/src/utils/Locale.js +229 -0
  40. package/src/utils/Mixed.js +887 -0
  41. package/src/utils/Now.js +234 -0
  42. package/src/utils/Number.js +238 -0
  43. package/src/utils/Object.js +655 -0
  44. package/src/utils/Route.js +67 -0
  45. package/src/utils/Runner.js +327 -0
  46. package/src/utils/String.js +618 -0
  47. package/src/{library/element.js → wip/Element.js} +90 -16
  48. package/src/{library/map.js → wip/Map.js} +256 -40
  49. package/types/dom/DomAttribute.d.ts +137 -0
  50. package/types/dom/DomBuilder.d.ts +67 -0
  51. package/types/dom/DomEvent.d.ts +103 -0
  52. package/types/dom/DomFinder.d.ts +321 -0
  53. package/types/dom/DomForm.d.ts +21 -0
  54. package/types/dom/DomGlobal.d.ts +79 -0
  55. package/types/dom/DomInview.d.ts +114 -0
  56. package/types/dom/DomMeta.d.ts +29 -0
  57. package/types/dom/DomObserver.d.ts +21 -0
  58. package/types/dom/DomRectangle.d.ts +270 -0
  59. package/types/format/FormatFile.d.ts +18 -0
  60. package/types/format/FormatOption.d.ts +40 -0
  61. package/types/format/FormatParam.d.ts +39 -0
  62. package/types/format/FormatParser.d.ts +46 -0
  63. package/types/format/FormatUrl.d.ts +17 -0
  64. package/types/index.browser.d.ts +1 -0
  65. package/types/index.esm.d.ts +52 -0
  66. package/types/now/NowDefault.d.ts +183 -0
  67. package/types/now/NowFormat.d.ts +70 -0
  68. package/types/now/NowGrid.d.ts +107 -0
  69. package/types/now/NowHuman.d.ts +37 -0
  70. package/types/now/NowMatch.d.ts +108 -0
  71. package/types/now/NowRange.d.ts +21 -0
  72. package/types/now/NowWalker.d.ts +301 -0
  73. package/types/tool/scope.d.ts +24 -0
  74. package/types/utils/Array.d.ts +480 -0
  75. package/types/utils/Cookie.d.ts +60 -0
  76. package/types/utils/Data.d.ts +91 -0
  77. package/types/utils/Dom.d.ts +138 -0
  78. package/types/utils/Event.d.ts +58 -0
  79. package/types/utils/Format.d.ts +37 -0
  80. package/types/utils/Hash.d.ts +81 -0
  81. package/types/utils/Locale.d.ts +115 -0
  82. package/types/utils/Mixed.d.ts +469 -0
  83. package/types/utils/Now.d.ts +125 -0
  84. package/types/utils/Number.d.ts +127 -0
  85. package/types/utils/Object.d.ts +255 -0
  86. package/types/utils/Route.d.ts +37 -0
  87. package/types/utils/Runner.d.ts +139 -0
  88. package/types/utils/String.d.ts +330 -0
  89. package/types/wip/Element.d.ts +119 -0
  90. package/types/wip/Map.d.ts +254 -0
  91. package/dist/.ignore.js +0 -0
  92. package/dist/pico-js.js +0 -2
  93. package/dist/pico-js.js.map +0 -1
  94. package/src/element/default.js +0 -46
  95. package/src/element/example.js +0 -58
  96. package/src/index.js +0 -90
  97. package/src/library/cookie.js +0 -123
  98. package/src/library/data.js +0 -111
  99. package/src/library/event.js +0 -91
  100. package/src/library/locale.js +0 -84
  101. package/src/library/queue.js +0 -64
  102. package/src/library/route.js +0 -28
  103. package/src/utility/any.js +0 -369
  104. package/src/utility/array.js +0 -410
  105. package/src/utility/dom.js +0 -1425
  106. package/src/utility/now.js +0 -544
  107. package/src/utility/number.js +0 -128
  108. package/src/utility/object.js +0 -429
  109. package/src/utility/string.js +0 -328
  110. package/types/index.d.ts +0 -77
  111. package/types/library/cookie.d.ts +0 -10
  112. package/types/library/data.d.ts +0 -15
  113. package/types/library/element.d.ts +0 -22
  114. package/types/library/event.d.ts +0 -13
  115. package/types/library/locale.d.ts +0 -14
  116. package/types/library/map.d.ts +0 -43
  117. package/types/library/queue.d.ts +0 -18
  118. package/types/library/route.d.ts +0 -11
  119. package/types/utility/any.d.ts +0 -35
  120. package/types/utility/array.d.ts +0 -46
  121. package/types/utility/dom.d.ts +0 -101
  122. package/types/utility/now.d.ts +0 -79
  123. package/types/utility/number.d.ts +0 -17
  124. package/types/utility/object.d.ts +0 -29
  125. package/types/utility/string.d.ts +0 -26
@@ -0,0 +1,986 @@
1
+ import { Obj, Mix, Arr } from "#src/index.esm.js";
2
+
3
+ export class PicoArray
4
+ {
5
+
6
+ /**
7
+ * Wrap value into an array
8
+ *
9
+ * @example Arr.all(1) // => [1]
10
+ * @example Arr.all([1]) // => [1]
11
+ *
12
+ * @param {any} value Value to wrap
13
+ * @returns {Array<any>} Wrapped array
14
+ */
15
+ static all(value)
16
+ {
17
+ return Mix.isArr(value) ? value : [value];
18
+ }
19
+
20
+ /**
21
+ * Get item at index or fallback
22
+ *
23
+ * @example Arr.get(["a"], 0) // => "a"
24
+ * @example Arr.get(["a"], 9, null) // => null
25
+ *
26
+ * @param {any} value Array-like value
27
+ * @param {number} index Index to read
28
+ * @param {any} [fallback] Fallback value
29
+ * @returns {any} Item or fallback
30
+ */
31
+ static get(value, index, fallback = null)
32
+ {
33
+ if ( ! Mix.isArr(value) ) {
34
+ return value;
35
+ }
36
+
37
+ if ( value && value[index] ) {
38
+ return value[index];
39
+ }
40
+
41
+ return fallback;
42
+ }
43
+
44
+ /**
45
+ * Set item at index (mutates)
46
+ *
47
+ * @example Arr.set([1,2], 0, 9) // => [9,2]
48
+ *
49
+ * @param {Array<any>} target Target array
50
+ * @param {number} index Index to set
51
+ * @param {any} value Value to set
52
+ * @returns {any} Splice result
53
+ */
54
+ static set(target, index, value)
55
+ {
56
+ return this.splice(target, index, 1, value);
57
+ }
58
+
59
+ /**
60
+ * Remove item at index (mutates)
61
+ *
62
+ * @example Arr.unset([1,2], 0) // => [1]
63
+ *
64
+ * @param {Array<any>} target Target array
65
+ * @param {number} index Index to remove
66
+ * @returns {any} Splice result
67
+ */
68
+ static unset(target, index)
69
+ {
70
+ return this.splice(target, index, 1);
71
+ }
72
+
73
+ /**
74
+ * Create array with callback values
75
+ *
76
+ * @example Arr.make(3) // => [0,1,2]
77
+ * @example Arr.make(2, "x") // => ["x","x"]
78
+ *
79
+ * @param {number} length Array length
80
+ * @param {any} [cb] Value or mapper
81
+ * @returns {Array<any>} Generated array
82
+ */
83
+ static make(length, cb = null)
84
+ {
85
+ let result = new Array(length);
86
+
87
+ if ( cb == null ) {
88
+ cb = (i) => i;
89
+ }
90
+
91
+ for ( let i = 0; i < length; i ++ ) {
92
+ result[i] = typeof cb === 'function' ? cb(i) : cb;
93
+ }
94
+
95
+ return result;
96
+ }
97
+
98
+ /**
99
+ * Check if array has value
100
+ *
101
+ * @example Arr.has([1,2], 2) // => true
102
+ * @example Arr.has([{id:1}], {id:1}) // => true
103
+ *
104
+ * @param {any} value List to search
105
+ * @param {any} search Search value
106
+ * @returns {boolean} True if found
107
+ */
108
+ static has(value, search)
109
+ {
110
+ if ( !Mix.isPrim(search) ) {
111
+ return this.findIndex(value, search) !== - 1;
112
+ }
113
+
114
+ if ( ! Mix.isArr(value) ) {
115
+ value = [value];
116
+ }
117
+
118
+ let index = value.findIndex((val) => {
119
+ return val == search;
120
+ });
121
+
122
+ return index !== - 1;
123
+ }
124
+
125
+ /**
126
+ * Get unique values as strings
127
+ *
128
+ * @example Arr.unique(["a","a"]) // => ["a"]
129
+ *
130
+ * @param {Array<any>} value Input list
131
+ * @returns {Array<any>} Unique list
132
+ */
133
+ static unique(value)
134
+ {
135
+ let buffer = {};
136
+
137
+ for ( const val of value ) {
138
+ buffer[val] = true;
139
+ }
140
+
141
+ return Mix.keys(buffer);
142
+ }
143
+
144
+ /**
145
+ * Check equal lengths for arrays
146
+ *
147
+ * @example Arr.lengths([1],[2]) // => true
148
+ *
149
+ * @param {Array<any>} value Base array
150
+ * @param {...Array<any>} args Other arrays
151
+ * @returns {boolean} True if equal
152
+ */
153
+ static lengths(value, ...args)
154
+ {
155
+ let length = value.length;
156
+
157
+ for ( let i = 0; i < args.length; i ++ ) {
158
+ if ( args[i].length !== length ) {
159
+ return false;
160
+ }
161
+ }
162
+
163
+ return true;
164
+ }
165
+
166
+ /**
167
+ * Get first item or fallback
168
+ *
169
+ * @example Arr.first([1,2]) // => 1
170
+ *
171
+ * @param {Array<any>} value Input array
172
+ * @param {any} [fallback] Fallback value
173
+ * @returns {any} First item
174
+ */
175
+ static first(value, fallback = null)
176
+ {
177
+ return this.get(value, 0, fallback);
178
+ }
179
+
180
+ /**
181
+ * Get second item or fallback
182
+ *
183
+ * @example Arr.second([1,2]) // => 2
184
+ *
185
+ * @param {Array<any>} value Input array
186
+ * @param {any} [fallback] Fallback value
187
+ * @returns {any} Second item
188
+ */
189
+ static second(value, fallback = null)
190
+ {
191
+ return this.get(value, 2, fallback);
192
+ }
193
+
194
+ /**
195
+ * Get third item or fallback
196
+ *
197
+ * @example Arr.third([1,2,3]) // => 3
198
+ *
199
+ * @param {Array<any>} value Input array
200
+ * @param {any} [fallback] Fallback value
201
+ * @returns {any} Third item
202
+ */
203
+ static third(value, fallback = null)
204
+ {
205
+ return this.get(value, 2, fallback);
206
+ }
207
+
208
+ /**
209
+ * Get last item or fallback
210
+ *
211
+ * @example Arr.last([1,2]) // => 2
212
+ *
213
+ * @param {Array<any>} value Input array
214
+ * @param {any} [fallback] Fallback value
215
+ * @returns {any} Last item
216
+ */
217
+ static last(value, fallback = null)
218
+ {
219
+ return this.get(value, value.length - 1, fallback);
220
+ }
221
+
222
+ /**
223
+ * Map values to new array
224
+ *
225
+ * @example Arr.each([1], v => v+1) // => [2]
226
+ *
227
+ * @param {any} value Input list
228
+ * @param {function} cb Map callback
229
+ * @param {any} [retval] Forced return
230
+ * @returns {any} Mapped array
231
+ */
232
+ static each(value, cb, retval = null)
233
+ {
234
+ let [isArr, keys] = [
235
+ Mix.isArr(value), Mix.keys(value)
236
+ ];
237
+
238
+ let fn = (key) => {
239
+ return isArr ? parseInt(key) : key;
240
+ };
241
+
242
+ let result = new Array(keys.length);
243
+
244
+ for (let i = 0; i < keys.length; i++) {
245
+ result[i] = cb(value[keys[i]], fn(keys[i]));
246
+ }
247
+
248
+ if ( retval != null ) {
249
+ return retval;
250
+ }
251
+
252
+ return result;
253
+ }
254
+
255
+ /**
256
+ * Map values in place (mutates)
257
+ *
258
+ * @example Arr.map([1], v => v+1) // => [2]
259
+ *
260
+ * @param {any} value Input list
261
+ * @param {function} cb Map callback
262
+ * @returns {any} Mutated input
263
+ */
264
+ static map(value, cb)
265
+ {
266
+ let [isArr, keys] = [
267
+ Mix.isArr(value), Mix.keys(value)
268
+ ];
269
+
270
+ let fn = (key) => {
271
+ return isArr ? parseInt(key) : key;
272
+ };
273
+
274
+ for ( let key of keys ) {
275
+ value[key] = cb(value[key], fn(key));
276
+ }
277
+
278
+ return value;
279
+ }
280
+
281
+ /**
282
+ * Recursively map nested arrays
283
+ *
284
+ * @example Arr.recursive([{c:[]}], "c", () => 1) // => list
285
+ *
286
+ * @param {any} value Input list
287
+ * @param {string} key Child key
288
+ * @param {function} cb Node callback
289
+ * @param {Array<any>} [cascade] Parent chain
290
+ * @returns {any} Mapped tree
291
+ */
292
+ static recursive(value, key, cb, cascade = [])
293
+ {
294
+ if ( value == null ) {
295
+ return value;
296
+ }
297
+
298
+ return this.map(value, (item) => {
299
+ return (this.recursive(item[key], key, cb, [
300
+ ...cascade, value
301
+ ]), cb(item, cascade));
302
+ });
303
+
304
+ // [{childs: [{ childs: [] } ] }, { childs: [] } ] }]
305
+ }
306
+
307
+ /**
308
+ * Get matching indexes by filter
309
+ *
310
+ * @example Arr.filterIndex([0,1], v => v) // => ["1"]
311
+ *
312
+ * @param {any} value Input list
313
+ * @param {any} [filter] Filter spec
314
+ * @returns {Array<string>} Matching keys
315
+ */
316
+ static filterIndex(value, filter = null)
317
+ {
318
+ if ( filter == null ) {
319
+ filter = (val) => !Mix.isEmpty(val);
320
+ }
321
+
322
+ return Mix.keys(value).filter((key) => {
323
+
324
+ if ( Mix.isFunc(filter) ) {
325
+ return filter.call({}, value[key], key);
326
+ }
327
+
328
+ if ( Mix.isRef(filter) ) {
329
+ return this.includes(value[key], filter);
330
+ }
331
+
332
+ return filter === value[key];
333
+ });
334
+ }
335
+
336
+ /**
337
+ * Filter values by filter
338
+ *
339
+ * @example Arr.filter([0,1], v => v) // => [1]
340
+ *
341
+ * @param {any} value Input list
342
+ * @param {any} [filter] Filter spec
343
+ * @returns {Array<any>} Filtered values
344
+ */
345
+ static filter(value, filter = null)
346
+ {
347
+ if ( filter == null ) {
348
+ filter = (val) => !Mix.isEmpty(val);
349
+ }
350
+
351
+ return Mix.vals(value).filter((val, key) => {
352
+
353
+ if ( Mix.isFunc(filter) ) {
354
+ return filter.call({}, val, key);
355
+ }
356
+
357
+ if ( Mix.isRef(filter) ) {
358
+ return this.includes(val, filter);
359
+ }
360
+
361
+ return filter === value[key];
362
+ });
363
+ }
364
+
365
+ /**
366
+ * Find index matching filter
367
+ *
368
+ * @example Arr.findIndex([1,2], 2) // => 1
369
+ *
370
+ * @param {Array<any>} value Input array
371
+ * @param {any} [filter] Filter spec
372
+ * @param {number} [fallback] Fallback index
373
+ * @returns {number} Found index
374
+ */
375
+ static findIndex(value, filter = null, fallback = - 1)
376
+ {
377
+ if ( filter == null ) {
378
+ filter = (val) => !Mix.isEmpty(val);
379
+ }
380
+
381
+ for ( let i = 0; i < value.length; i ++ ) {
382
+
383
+ if ( Mix.isFunc(filter) ) {
384
+ if ( filter.call({}, value[i], i) ) {
385
+ return i;
386
+ }
387
+ }
388
+
389
+ if ( Mix.isRef(filter) ) {
390
+ if ( this.includes(value[i], filter) ) {
391
+ return i;
392
+ }
393
+ }
394
+
395
+ if ( filter === value[i] ) return i;
396
+ }
397
+
398
+ return fallback;
399
+ }
400
+
401
+ /**
402
+ * Find value matching filter
403
+ *
404
+ * @example Arr.find([1,2], 2) // => 2
405
+ *
406
+ * @param {Array<any>} value Input array
407
+ * @param {any} [filter] Filter spec
408
+ * @param {any} [fallback] Fallback value
409
+ * @returns {any} Found value
410
+ */
411
+ static find(value, filter = null, fallback = null)
412
+ {
413
+ let index = this.findIndex(value, filter);
414
+
415
+ if ( index === - 1 ) {
416
+ return fallback;
417
+ }
418
+
419
+ return value[index];
420
+ }
421
+
422
+ /**
423
+ * Sort array by key or callback
424
+ *
425
+ * @example Arr.sort([{n:2},{n:1}], "n") // => list
426
+ *
427
+ * @param {any} value Input list
428
+ * @param {any} [key] Key or compare fn
429
+ * @returns {Array<any>} Sorted list
430
+ */
431
+ static sort(value, key = null)
432
+ {
433
+ if ( Mix.isFunc(key) ) {
434
+ return this.sortFunc(value, key);
435
+ }
436
+
437
+ if ( key != null ) {
438
+ return this.sortDeep(value, key);
439
+ }
440
+
441
+ return this.sortPrim(value)
442
+ }
443
+
444
+ /**
445
+ * Sort by compare callback
446
+ *
447
+ * @example Arr.sortFunc([2,1], (a,b)=>a-b) // => [1,2]
448
+ *
449
+ * @param {any} value Input list
450
+ * @param {function} cb Compare callback
451
+ * @returns {Array<any>} Sorted list
452
+ */
453
+ static sortFunc(value, cb)
454
+ {
455
+ let keys = Mix.keys(value).sort((a, b) => {
456
+ return cb.call({}, value[a], value[b]);
457
+ });
458
+
459
+ let result = [];
460
+
461
+ for ( const key of keys ) {
462
+ result.push(value[key]);
463
+ }
464
+
465
+ return result;
466
+ }
467
+
468
+ /**
469
+ * Sort by nested key value
470
+ *
471
+ * @example Arr.sortDeep([{a:{n:2}},{a:{n:1}}], "a.n") // => list
472
+ *
473
+ * @param {any} value Input list
474
+ * @param {any} key Key path
475
+ * @returns {Array<any>} Sorted list
476
+ */
477
+ static sortDeep(value, key)
478
+ {
479
+ let keys = Mix.keys(value).sort((a, b) => {
480
+ return Mix.compare(Obj.get(a, key), Obj.get(b, key));
481
+ });
482
+
483
+ let result = [];
484
+
485
+ for ( const key of keys ) {
486
+ result.push(value[key]);
487
+ }
488
+
489
+ return result;
490
+ }
491
+
492
+ /**
493
+ * Sort by primitive key order
494
+ *
495
+ * @example Arr.sortPrim(["b","a"]) // => ["a","b"]
496
+ *
497
+ * @param {any} value Input list
498
+ * @returns {Array<any>} Sorted list
499
+ */
500
+ static sortPrim(value)
501
+ {
502
+ let keys = Mix.keys(value).sort((a, b) => {
503
+ return Mix.compare(a, b);
504
+ });
505
+
506
+ let result = [];
507
+
508
+ for ( const key of keys ) {
509
+ result.push(value[key]);
510
+ }
511
+
512
+ return result;
513
+ }
514
+
515
+ /**
516
+ * Merge arrays (concat)
517
+ *
518
+ * @example Arr.merge([1],[2]) // => [1,2]
519
+ *
520
+ * @param {Array<any>} value Base array
521
+ * @param {...any} args Arrays to add
522
+ * @returns {Array<any>} Merged array
523
+ */
524
+ static merge(value, ...args)
525
+ {
526
+ return value.concat(...args);
527
+ }
528
+
529
+ /**
530
+ * Prepend items (mutates)
531
+ *
532
+ * @example Arr.prepend([2], 1) // => [1,2]
533
+ *
534
+ * @param {Array<any>} value Target array
535
+ * @param {...any} args Items to add
536
+ * @returns {Array<any>} Mutated array
537
+ */
538
+ static prepend(value, ...args)
539
+ {
540
+ return (value.unshift(...args), value);
541
+ }
542
+
543
+ /**
544
+ * Append items (mutates)
545
+ *
546
+ * @example Arr.append([1], 2) // => [1,2]
547
+ *
548
+ * @param {Array<any>} value Target array
549
+ * @param {...any} args Items to add
550
+ * @returns {Array<any>} Mutated array
551
+ */
552
+ static append(value, ...args)
553
+ {
554
+ return (value.push(...args), value);
555
+ }
556
+
557
+ /**
558
+ * Add item if not present
559
+ *
560
+ * @example Arr.add([1], 2) // => [1,2]
561
+ *
562
+ * @param {Array<any>} value Target array
563
+ * @param {any} target Item to add
564
+ * @param {any} [finder] Finder value
565
+ * @returns {Array<any>} Mutated array
566
+ */
567
+ static add(value, target, finder = null)
568
+ {
569
+ if ( finder == null ) {
570
+ finder = target;
571
+ }
572
+
573
+ if ( this.findIndex(value, finder) !== -1 ) {
574
+ return value;
575
+ }
576
+
577
+ return (value.push(target), value);
578
+ }
579
+
580
+ /**
581
+ * Replace existing item or add
582
+ *
583
+ * @example Arr.replace([1], 2) // => [1,2]
584
+ *
585
+ * @param {Array<any>} value Target array
586
+ * @param {any} target Item to add
587
+ * @param {any} [finder] Finder value
588
+ * @returns {Array<any>} Mutated array
589
+ */
590
+ static replace(value, target, finder = null)
591
+ {
592
+ if ( finder == null ) {
593
+ finder = target;
594
+ }
595
+
596
+ let index = this.findIndex(value, finder);
597
+
598
+ if ( index !== -1 ) {
599
+ this.splice(value, index, 1);
600
+ }
601
+
602
+ return (value.push(target), value);
603
+ }
604
+
605
+ /**
606
+ * Remove item if present
607
+ *
608
+ * @example Arr.remove([1,2], 1) // => [2]
609
+ *
610
+ * @param {Array<any>} value Target array
611
+ * @param {any} target Item to remove
612
+ * @param {any} [finder] Finder value
613
+ * @returns {Array<any>} Mutated array
614
+ */
615
+ static remove(value, target, finder = null)
616
+ {
617
+ if ( finder == null ) {
618
+ finder = target;
619
+ }
620
+
621
+ let index = this.findIndex(value, finder);
622
+
623
+ if ( index === -1 ) {
624
+ return value;
625
+ }
626
+
627
+ return (this.splice(value, index, 1), value);
628
+ }
629
+
630
+ /**
631
+ * Toggle item in array
632
+ *
633
+ * @example Arr.toggle([1], 1) // => []
634
+ * @example Arr.toggle([], 1) // => [1]
635
+ *
636
+ * @param {Array<any>} value Target array
637
+ * @param {any} target Item to toggle
638
+ * @param {any} [finder] Finder value
639
+ * @returns {Array<any>} Mutated array
640
+ */
641
+ static toggle(value, target, finder = null)
642
+ {
643
+ if ( finder == null ) {
644
+ finder = target;
645
+ }
646
+
647
+ let index = this.findIndex(value, finder);
648
+
649
+ if ( index === -1 ) {
650
+ return (value.push(target), value);
651
+ }
652
+
653
+ return (this.splice(value, index, 1), value);
654
+ }
655
+
656
+ /**
657
+ * Insert item at index (mutates)
658
+ *
659
+ * @example Arr.insert([1,3], 1, 2) // => [1,2,3]
660
+ *
661
+ * @param {Array<any>} value Target array
662
+ * @param {number} index Insert index
663
+ * @param {any} target Item to insert
664
+ * @returns {Array<any>} Mutated array
665
+ */
666
+ static insert(value, index, target)
667
+ {
668
+ return (this.splice(value, index, 0, target), value);
669
+ }
670
+
671
+ /**
672
+ * Slice array from index
673
+ *
674
+ * @example Arr.slice([1,2,3], 1, 2) // => [2,3]
675
+ *
676
+ * @param {Array<any>} value Source array
677
+ * @param {number} index Start index
678
+ * @param {number} [length] Slice length
679
+ * @returns {Array<any>} Sliced array
680
+ */
681
+ static slice(value, index, length = 1)
682
+ {
683
+ return value.slice(parseInt(index), length);
684
+ }
685
+
686
+ /**
687
+ * Splice array (mutates)
688
+ *
689
+ * @example Arr.splice([1,2], 0, 1) // => [1]
690
+ *
691
+ * @param {Array<any>} value Target array
692
+ * @param {number} index Start index
693
+ * @param {number} [length] Remove count
694
+ * @param {...any} args Items to add
695
+ * @returns {any} Splice result
696
+ */
697
+ static splice(value, index, length = 1, ...args)
698
+ {
699
+ return value.splice(parseInt(index), length, ...args);
700
+ }
701
+
702
+ /**
703
+ * Splice multiple indexes
704
+ *
705
+ * @example Arr.splices([1,2,3],[0,2]) // => [2]
706
+ *
707
+ * @param {Array<any>} value Target array
708
+ * @param {Array<number>} indexies Index list
709
+ * @param {number} [length] Remove count
710
+ * @returns {Array<any>} Mutated array
711
+ */
712
+ static splices(value, indexies, length = 1)
713
+ {
714
+ this.each(indexies, (index) => {
715
+ this.splice(value, index, length);
716
+ });
717
+
718
+ return value;
719
+ }
720
+
721
+ /**
722
+ * Deep clone array/object
723
+ *
724
+ * @example Arr.clone([1,{a:1}]) // => new array
725
+ *
726
+ * @param {any} value Value to clone
727
+ * @returns {any} Cloned value
728
+ */
729
+ static clone(value)
730
+ {
731
+ if ( Mix.isPrim(value) ) {
732
+ return value;
733
+ }
734
+
735
+ if ( Mix.isObj(value) ) {
736
+ return Obj.clone(value);
737
+ }
738
+
739
+ if ( ! Mix.isArr(value) ) {
740
+ return value;
741
+ }
742
+
743
+ let result = new Array(value.length);
744
+
745
+ for ( let i = 0; i < value.length; i ++ ) {
746
+ result[i] = this.clone(value[i]);
747
+ }
748
+
749
+ return result;
750
+ }
751
+
752
+ /**
753
+ * Get items not in others
754
+ *
755
+ * @example Arr.diff([1,2],[2]) // => [1]
756
+ *
757
+ * @param {...Array<any>} args Arrays to diff
758
+ * @returns {Array<any>} Difference list
759
+ */
760
+ static diff(...args)
761
+ {
762
+ return args.reduce((a, c) => {
763
+ return a.filter(i => !c.includes(i))
764
+ });
765
+ }
766
+
767
+ /**
768
+ * Get intersecting items
769
+ *
770
+ * @example Arr.isect([1,2],[2,3]) // => [2]
771
+ *
772
+ * @param {...Array<any>} args Arrays to intersect
773
+ * @returns {Array<any>} Intersection list
774
+ */
775
+ static isect(...args)
776
+ {
777
+ return args.reduce((a, c) => {
778
+ return a.filter(i => c.includes(i))
779
+ });
780
+ }
781
+
782
+ /**
783
+ * Extract property values from list
784
+ *
785
+ * @example Arr.extract([{id:1}], "id") // => [1]
786
+ *
787
+ * @param {Array<any>} value Input list
788
+ * @param {any} key Key path
789
+ * @returns {Array<any>} Extracted list
790
+ */
791
+ static extract(value, key)
792
+ {
793
+ let result = new Array(value.length);
794
+
795
+ for ( let i = 0; i < value.length; i ++ ) {
796
+ result[i] = Obj.get(value[i], key);
797
+ }
798
+
799
+ return result;
800
+ }
801
+
802
+ /**
803
+ * Reduce list values
804
+ *
805
+ * @example Arr.reduce([1,2], (a,c)=>a+c, 0) // => 3
806
+ *
807
+ * @param {any} value Input list
808
+ * @param {function} callback Reducer callback
809
+ * @param {any} accumulator Start value
810
+ * @returns {any} Reduced value
811
+ */
812
+ static reduce(value, callback, accumulator)
813
+ {
814
+ return Mix.vals(value).reduce(callback, accumulator);
815
+ }
816
+
817
+ /**
818
+ * Split array into chunks
819
+ *
820
+ * @example Arr.chunk([1,2,3], 2) // => [[1,2],[3]]
821
+ *
822
+ * @param {Array<any>} value Source array
823
+ * @param {number} [chunk] Chunk size
824
+ * @returns {Array<Array<any>>} Chunked list
825
+ */
826
+ static chunk(value, chunk = 10)
827
+ {
828
+ let res = [];
829
+
830
+ for ( let i = 0; i < value.length; i += chunk ) {
831
+ res.push(value.slice(i, i + chunk));
832
+ }
833
+
834
+ return res;
835
+ }
836
+
837
+ /**
838
+ * Check if value includes search
839
+ *
840
+ * @example Arr.includes([1,2], 2) // => true
841
+ * @example Arr.includes([{a:1}], {a:1}) // => true
842
+ *
843
+ * @param {any} value Target value
844
+ * @param {any} search Search spec
845
+ * @returns {boolean} True if includes
846
+ */
847
+ static includes(value, search)
848
+ {
849
+ if ( Mix.isObj(search) ) {
850
+ return Obj.includes(value, search);
851
+ }
852
+
853
+ if ( ! Mix.isArr(search) ) {
854
+ return value === search;
855
+ }
856
+
857
+ let [result, length] = [
858
+ false, search.length,
859
+ ];
860
+
861
+ if ( length === 0 ) {
862
+ return true;
863
+ }
864
+
865
+ for ( let i = 0; result === false && i < length; i++) {
866
+ result ||= this.has(value, search[i]);
867
+ }
868
+
869
+ return result;
870
+ }
871
+
872
+ /**
873
+ * Check array contains all values
874
+ *
875
+ * @example Arr.contains([1,2], [2]) // => true
876
+ *
877
+ * @param {any} arr Target array
878
+ * @param {any} val Required values
879
+ * @returns {boolean} True if contains
880
+ */
881
+ static contains(arr, val)
882
+ {
883
+ let result = true;
884
+
885
+ for ( let key of Mix.vals(val) ) {
886
+ result &&= Mix.vals(arr).indexOf(key) !== -1;
887
+ }
888
+
889
+ return result;
890
+ }
891
+
892
+ /**
893
+ * Check arrays match (set-like)
894
+ *
895
+ * @example Arr.matches([1,2], [2,1]) // => true
896
+ *
897
+ * @param {any} value Target list
898
+ * @param {any} search Search spec
899
+ * @returns {boolean} True if matches
900
+ */
901
+ static matches(value, search)
902
+ {
903
+ if ( Mix.isObj(search) ) {
904
+ return Obj.matches(value, search);
905
+ }
906
+
907
+ if ( ! Mix.isArr(value) ) {
908
+ return value === search;
909
+ }
910
+
911
+ search = this.unique(search);
912
+
913
+ let [result, length] = [
914
+ true, search.length,
915
+ ];
916
+
917
+ if ( value.length !== search.length ) {
918
+ return false;
919
+ }
920
+
921
+ for ( let i = 0; result === true && i < length; i++) {
922
+ result &&= this.has(value, search[i]);
923
+ }
924
+
925
+ return result;
926
+ }
927
+
928
+ }
929
+
930
+ /**
931
+ * @see PicoArray.unset
932
+ */
933
+ PicoArray.removeIndex = (...args) => {
934
+ console.warn('Arr.removeIndex() is deprecated, use Arr.unset() instead.');
935
+ return Arr.unset(...args);
936
+ };
937
+
938
+ /**
939
+ * @see PicoArray.sortPrim
940
+ */
941
+ PicoArray.sortString = (...args) => {
942
+ console.warn('Arr.sortString() is deprecated, use Arr.sortPrim() instead.');
943
+ return Arr.sortPrim(...args);
944
+ };
945
+
946
+ /**
947
+ * @see PicoArray.append
948
+ */
949
+ PicoArray.push = (...args) => {
950
+ console.warn('Arr.push() is deprecated, use Arr.append() instead.');
951
+ return Arr.append(...args);
952
+ };
953
+
954
+ /**
955
+ * @see PicoArray.merge
956
+ */
957
+ PicoArray.concat = (...args) => {
958
+ console.warn('Arr.concat() is deprecated, use Arr.merge() instead.');
959
+ return Arr.merge(...args);
960
+ };
961
+
962
+ /**
963
+ * @see PicoArray.matches
964
+ */
965
+ PicoArray.equal = (...args) => {
966
+ console.warn('Arr.equal() is deprecated, use Arr.matches() instead.');
967
+ return Arr.matches(...args);
968
+ };
969
+
970
+ /**
971
+ * @see PicoArray.diff
972
+ */
973
+ PicoArray.diffrence = (...args) => {
974
+ console.warn('Arr.diffrence() is deprecated, use Arr.diff() instead.');
975
+ return Arr.diff(...args);
976
+ };
977
+
978
+ /**
979
+ * @see PicoArray.isect
980
+ */
981
+ PicoArray.intersect = (...args) => {
982
+ console.warn('Arr.intersect() is deprecated, use Arr.isect() instead.');
983
+ return Arr.isect(...args);
984
+ };
985
+
986
+ export default PicoArray;