ts-data-forge 12.2.1 → 13.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 (80) hide show
  1. package/README.md +3 -6
  2. package/dist/array/impl/array-utils-creation.d.mts +1 -1
  3. package/dist/array/impl/array-utils-creation.d.mts.map +1 -1
  4. package/dist/array/impl/array-utils-element-access.d.mts +1 -1
  5. package/dist/array/impl/array-utils-element-access.d.mts.map +1 -1
  6. package/dist/array/impl/array-utils-element-access.mjs +10 -13
  7. package/dist/array/impl/array-utils-element-access.mjs.map +1 -1
  8. package/dist/array/impl/array-utils-iterators.d.mts +1 -1
  9. package/dist/array/impl/array-utils-iterators.d.mts.map +1 -1
  10. package/dist/array/impl/array-utils-length-bounded-array-cast.d.mts.map +1 -1
  11. package/dist/array/impl/array-utils-length-bounded-array-cast.mjs +53 -53
  12. package/dist/array/impl/array-utils-length-bounded-array-cast.mjs.map +1 -1
  13. package/dist/array/impl/array-utils-modification.d.mts.map +1 -1
  14. package/dist/array/impl/array-utils-modification.mjs +61 -70
  15. package/dist/array/impl/array-utils-modification.mjs.map +1 -1
  16. package/dist/array/impl/array-utils-reducing-value.d.mts.map +1 -1
  17. package/dist/array/impl/array-utils-reducing-value.mjs +37 -47
  18. package/dist/array/impl/array-utils-reducing-value.mjs.map +1 -1
  19. package/dist/array/impl/array-utils-search.d.mts.map +1 -1
  20. package/dist/array/impl/array-utils-search.mjs +80 -92
  21. package/dist/array/impl/array-utils-search.mjs.map +1 -1
  22. package/dist/array/impl/array-utils-set-op.d.mts +1 -1
  23. package/dist/array/impl/array-utils-set-op.d.mts.map +1 -1
  24. package/dist/array/impl/array-utils-size.d.mts +1 -1
  25. package/dist/array/impl/array-utils-size.d.mts.map +1 -1
  26. package/dist/array/impl/array-utils-slice-clamped.mjs +9 -10
  27. package/dist/array/impl/array-utils-slice-clamped.mjs.map +1 -1
  28. package/dist/array/impl/array-utils-slicing.d.mts +1 -1
  29. package/dist/array/impl/array-utils-slicing.d.mts.map +1 -1
  30. package/dist/array/impl/array-utils-slicing.mjs +20 -32
  31. package/dist/array/impl/array-utils-slicing.mjs.map +1 -1
  32. package/dist/array/impl/array-utils-transformation.d.mts.map +1 -1
  33. package/dist/array/impl/array-utils-transformation.mjs +41 -52
  34. package/dist/array/impl/array-utils-transformation.mjs.map +1 -1
  35. package/dist/array/impl/array-utils-validation.d.mts +6 -4
  36. package/dist/array/impl/array-utils-validation.d.mts.map +1 -1
  37. package/dist/array/impl/array-utils-validation.mjs +10 -16
  38. package/dist/array/impl/array-utils-validation.mjs.map +1 -1
  39. package/dist/json/json.mjs +1 -1
  40. package/dist/json/json.mjs.map +1 -1
  41. package/dist/number/branded-types/finite-number.d.mts +6 -3
  42. package/dist/number/branded-types/finite-number.d.mts.map +1 -1
  43. package/dist/number/branded-types/negative-finite-number.d.mts +8 -4
  44. package/dist/number/branded-types/negative-finite-number.d.mts.map +1 -1
  45. package/dist/number/branded-types/negative-int.d.mts +2 -1
  46. package/dist/number/branded-types/negative-int.d.mts.map +1 -1
  47. package/dist/number/branded-types/negative-safe-int.d.mts +2 -1
  48. package/dist/number/branded-types/negative-safe-int.d.mts.map +1 -1
  49. package/dist/number/branded-types/non-negative-finite-number.d.mts +6 -3
  50. package/dist/number/branded-types/non-negative-finite-number.d.mts.map +1 -1
  51. package/dist/number/branded-types/non-positive-finite-number.d.mts +6 -3
  52. package/dist/number/branded-types/non-positive-finite-number.d.mts.map +1 -1
  53. package/dist/number/branded-types/non-zero-finite-number.d.mts +6 -3
  54. package/dist/number/branded-types/non-zero-finite-number.d.mts.map +1 -1
  55. package/dist/number/branded-types/positive-finite-number.d.mts +6 -3
  56. package/dist/number/branded-types/positive-finite-number.d.mts.map +1 -1
  57. package/dist/number/enum/int8.d.mts +26 -13
  58. package/dist/number/enum/int8.d.mts.map +1 -1
  59. package/dist/number/enum/uint8.d.mts +24 -12
  60. package/dist/number/enum/uint8.d.mts.map +1 -1
  61. package/dist/others/if-then.d.mts +1 -1
  62. package/dist/others/if-then.d.mts.map +1 -1
  63. package/dist/string/str.d.mts.map +1 -1
  64. package/dist/string/str.mjs +52 -52
  65. package/dist/string/str.mjs.map +1 -1
  66. package/package.json +8 -4
  67. package/src/array/impl/array-utils-element-access.mts +15 -16
  68. package/src/array/impl/array-utils-length-bounded-array-cast.mts +73 -60
  69. package/src/array/impl/array-utils-modification.mts +96 -94
  70. package/src/array/impl/array-utils-reducing-value.mts +68 -57
  71. package/src/array/impl/array-utils-search.mts +146 -148
  72. package/src/array/impl/array-utils-slice-clamped.mts +16 -14
  73. package/src/array/impl/array-utils-slicing.mts +37 -40
  74. package/src/array/impl/array-utils-transformation.mts +64 -62
  75. package/src/array/impl/array-utils-transformation.test.mts +1 -1
  76. package/src/array/impl/array-utils-validation.mts +29 -27
  77. package/src/collections/iset.test.mts +2 -2
  78. package/src/functional/pipe.test.mts +1 -1
  79. package/src/json/json.mts +1 -1
  80. package/src/string/str.mts +74 -61
@@ -239,24 +239,24 @@ export function count<E>(
239
239
  | readonly [predicate: (value: E, index: SizeType.Arr) => boolean]
240
240
  ): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr) {
241
241
  switch (args.length) {
242
- case 2: {
243
- const [array, predicate] = args;
244
-
245
- return array.reduce<Uint32>(
246
- (acc, curr, index) =>
247
- predicate(curr, asUint32(index)) ? Uint32.add(acc, 1) : acc,
248
- asUint32(0),
249
- );
250
- }
242
+ case 2:
243
+ return countImpl(...args);
251
244
 
252
- case 1: {
253
- const [predicate] = args;
254
-
255
- return (array) => count(array, predicate);
256
- }
245
+ case 1:
246
+ return (array) => countImpl(array, ...args);
257
247
  }
258
248
  }
259
249
 
250
+ const countImpl = <E,>(
251
+ array: readonly E[],
252
+ predicate: (value: E, index: SizeType.Arr) => boolean,
253
+ ): SizeType.Arr =>
254
+ array.reduce<Uint32>(
255
+ (acc, curr, index) =>
256
+ predicate(curr, asUint32(index)) ? Uint32.add(acc, 1) : acc,
257
+ asUint32(0),
258
+ );
259
+
260
260
  /**
261
261
  * Groups elements by a key and counts the elements in each group.
262
262
  *
@@ -295,29 +295,30 @@ export function countBy<E, G extends MapSetKeyType>(
295
295
  | readonly [grouper: (value: E, index: SizeType.Arr) => G]
296
296
  ): IMap<G, SizeType.Arr> | ((array: readonly E[]) => IMap<G, SizeType.Arr>) {
297
297
  switch (args.length) {
298
- case 2: {
299
- const [array, grouper] = args;
300
-
301
- const mut_groups = new Map<G, SizeType.Arr>();
302
-
303
- for (const [index, e] of array.entries()) {
304
- const key = grouper(e, asUint32(index));
298
+ case 2:
299
+ return countByImpl(...args);
305
300
 
306
- const curr = mut_groups.get(key) ?? 0;
301
+ case 1:
302
+ return (array) => countByImpl(array, ...args);
303
+ }
304
+ }
307
305
 
308
- mut_groups.set(key, asUint32(curr + 1));
309
- }
306
+ const countByImpl = <E, G extends MapSetKeyType>(
307
+ array: readonly E[],
308
+ grouper: (value: E, index: SizeType.Arr) => G,
309
+ ): IMap<G, SizeType.Arr> => {
310
+ const mut_groups = new Map<G, SizeType.Arr>();
310
311
 
311
- return IMap.create(mut_groups);
312
- }
312
+ for (const [index, e] of array.entries()) {
313
+ const key = grouper(e, asUint32(index));
313
314
 
314
- case 1: {
315
- const [grouper] = args;
315
+ const curr = mut_groups.get(key) ?? 0;
316
316
 
317
- return (array) => countBy(array, grouper);
318
- }
317
+ mut_groups.set(key, asUint32(curr + 1));
319
318
  }
320
- }
319
+
320
+ return IMap.create(mut_groups);
321
+ };
321
322
 
322
323
  /**
323
324
  * Reduces an array to a single value from left to right.
@@ -379,23 +380,28 @@ export function foldl<E, P>(
379
380
  ]
380
381
  ): P | ((array: readonly E[]) => P) {
381
382
  switch (args.length) {
382
- case 3: {
383
- const [array, callbackfn, initialValue] = args;
384
-
385
- return array.reduce(
386
- (prev, curr, index) => callbackfn(prev, curr, asUint32(index)),
387
- initialValue,
388
- );
389
- }
383
+ case 3:
384
+ return foldlImpl(...args);
390
385
 
391
- case 2: {
392
- const [callbackfn, initialValue] = args;
393
-
394
- return (array) => foldl(array, callbackfn, initialValue);
395
- }
386
+ case 2:
387
+ return (array) => foldlImpl(array, ...args);
396
388
  }
397
389
  }
398
390
 
391
+ const foldlImpl = <E, P>(
392
+ array: readonly E[],
393
+ callbackfn: (
394
+ previousValue: P,
395
+ currentValue: E,
396
+ currentIndex: SizeType.Arr,
397
+ ) => P,
398
+ initialValue: P,
399
+ ): P =>
400
+ array.reduce(
401
+ (prev, curr, index) => callbackfn(prev, curr, asUint32(index)),
402
+ initialValue,
403
+ );
404
+
399
405
  /**
400
406
  * Reduces an array to a single value from right to left.
401
407
  *
@@ -456,23 +462,28 @@ export function foldr<E, P>(
456
462
  ]
457
463
  ): P | ((array: readonly E[]) => P) {
458
464
  switch (args.length) {
459
- case 3: {
460
- const [array, callbackfn, initialValue] = args;
461
-
462
- return array.reduceRight(
463
- (prev, curr, index) => callbackfn(prev, curr, asUint32(index)),
464
- initialValue,
465
- );
466
- }
467
-
468
- case 2: {
469
- const [callbackfn, initialValue] = args;
465
+ case 3:
466
+ return foldrImpl(...args);
470
467
 
471
- return (array) => foldr(array, callbackfn, initialValue);
472
- }
468
+ case 2:
469
+ return (array) => foldrImpl(array, ...args);
473
470
  }
474
471
  }
475
472
 
473
+ const foldrImpl = <E, P>(
474
+ array: readonly E[],
475
+ callbackfn: (
476
+ previousValue: P,
477
+ currentValue: E,
478
+ currentIndex: SizeType.Arr,
479
+ ) => P,
480
+ initialValue: P,
481
+ ): P =>
482
+ array.reduceRight(
483
+ (prev, curr, index) => callbackfn(prev, curr, asUint32(index)),
484
+ initialValue,
485
+ );
486
+
476
487
  /**
477
488
  * Calculates the sum of numbers in an array.
478
489
  *
@@ -62,43 +62,39 @@ export function find<E>(
62
62
  ]
63
63
  ): Optional<E> | ((array: readonly E[]) => Optional<E>) {
64
64
  switch (args.length) {
65
- case 2: {
66
- const [array, predicate] = args;
67
-
68
- const foundIndex = array.findIndex(
69
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
70
- predicate as () => boolean,
71
- );
72
-
73
- expectType<
74
- Parameters<typeof array.findIndex>[0],
75
- (value: E, index: number, arr: readonly E[]) => unknown
76
- >('=');
77
-
78
- expectType<
79
- typeof predicate,
80
- (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean
81
- >('=');
82
-
83
- return foundIndex === -1
84
- ? Optional.none
85
- : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
86
- Optional.some(array[foundIndex]!);
87
- }
88
-
89
- case 1: {
90
- const [predicate] = args;
91
-
92
- expectType<
93
- typeof predicate,
94
- (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean
95
- >('=');
96
-
97
- return (array) => find(array, predicate);
98
- }
65
+ case 2:
66
+ return findImpl(...args);
67
+
68
+ case 1:
69
+ return (array) => findImpl(array, ...args);
99
70
  }
100
71
  }
101
72
 
73
+ const findImpl = <E,>(
74
+ array: readonly E[],
75
+ predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean,
76
+ ): Optional<E> => {
77
+ const foundIndex = array.findIndex(
78
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
79
+ predicate as () => boolean,
80
+ );
81
+
82
+ expectType<
83
+ Parameters<typeof array.findIndex>[0],
84
+ (value: E, index: number, arr: readonly E[]) => unknown
85
+ >('=');
86
+
87
+ expectType<
88
+ typeof predicate,
89
+ (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean
90
+ >('=');
91
+
92
+ return foundIndex === -1
93
+ ? Optional.none
94
+ : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
95
+ Optional.some(array[foundIndex]!);
96
+ };
97
+
102
98
  /**
103
99
  * Finds the last element that satisfies a predicate.
104
100
  *
@@ -149,43 +145,39 @@ export function findLast<E>(
149
145
  ]
150
146
  ): Optional<E> | ((array: readonly E[]) => Optional<E>) {
151
147
  switch (args.length) {
152
- case 2: {
153
- const [array, predicate] = args;
154
-
155
- const foundIndex = array.findLastIndex(
156
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
157
- predicate as () => boolean,
158
- );
159
-
160
- expectType<
161
- Parameters<typeof array.findIndex>[0],
162
- (value: E, index: number, arr: readonly E[]) => unknown
163
- >('=');
164
-
165
- expectType<
166
- typeof predicate,
167
- (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean
168
- >('=');
169
-
170
- return foundIndex === -1
171
- ? Optional.none
172
- : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
173
- Optional.some(array[foundIndex]!);
174
- }
175
-
176
- case 1: {
177
- const [predicate] = args;
178
-
179
- expectType<
180
- typeof predicate,
181
- (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean
182
- >('=');
183
-
184
- return (array) => findLast(array, predicate);
185
- }
148
+ case 2:
149
+ return findLastImpl(...args);
150
+
151
+ case 1:
152
+ return (array) => findLastImpl(array, ...args);
186
153
  }
187
154
  }
188
155
 
156
+ const findLastImpl = <E,>(
157
+ array: readonly E[],
158
+ predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean,
159
+ ): Optional<E> => {
160
+ const foundIndex = array.findLastIndex(
161
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
162
+ predicate as () => boolean,
163
+ );
164
+
165
+ expectType<
166
+ Parameters<typeof array.findIndex>[0],
167
+ (value: E, index: number, arr: readonly E[]) => unknown
168
+ >('=');
169
+
170
+ expectType<
171
+ typeof predicate,
172
+ (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean
173
+ >('=');
174
+
175
+ return foundIndex === -1
176
+ ? Optional.none
177
+ : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
178
+ Optional.some(array[foundIndex]!);
179
+ };
180
+
189
181
  /**
190
182
  * Finds the index of the first element that satisfies a predicate.
191
183
  *
@@ -233,25 +225,25 @@ export function findIndex<E>(
233
225
  ]
234
226
  ): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr | -1) | -1 {
235
227
  switch (args.length) {
236
- case 2: {
237
- const [array, predicate] = args;
238
-
239
- return pipe(
240
- array.findIndex(
241
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
242
- predicate as (value: E, index: number) => boolean,
243
- ),
244
- ).map((idx) => (idx >= 0 ? asUint32(idx) : -1)).value;
245
- }
246
-
247
- case 1: {
248
- const [predicate] = args;
249
-
250
- return (array) => findIndex(array, predicate);
251
- }
228
+ case 2:
229
+ return findIndexImpl(...args);
230
+
231
+ case 1:
232
+ return (array) => findIndexImpl(array, ...args);
252
233
  }
253
234
  }
254
235
 
236
+ const findIndexImpl = <E,>(
237
+ array: readonly E[],
238
+ predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean,
239
+ ): SizeType.Arr | -1 =>
240
+ pipe(
241
+ array.findIndex(
242
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
243
+ predicate as (value: E, index: number) => boolean,
244
+ ),
245
+ ).map((idx) => (idx >= 0 ? asUint32(idx) : -1)).value;
246
+
255
247
  /**
256
248
  * Finds the index of the last element that satisfies a predicate.
257
249
  *
@@ -299,25 +291,25 @@ export function findLastIndex<E>(
299
291
  ]
300
292
  ): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr | -1) | -1 {
301
293
  switch (args.length) {
302
- case 2: {
303
- const [array, predicate] = args;
304
-
305
- return pipe(
306
- array.findLastIndex(
307
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
308
- predicate as (value: E, index: number) => boolean,
309
- ),
310
- ).map((idx) => (idx >= 0 ? asUint32(idx) : -1)).value;
311
- }
312
-
313
- case 1: {
314
- const [predicate] = args;
315
-
316
- return (array) => findLastIndex(array, predicate);
317
- }
294
+ case 2:
295
+ return findLastIndexImpl(...args);
296
+
297
+ case 1:
298
+ return (array) => findLastIndexImpl(array, ...args);
318
299
  }
319
300
  }
320
301
 
302
+ const findLastIndexImpl = <E,>(
303
+ array: readonly E[],
304
+ predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean,
305
+ ): SizeType.Arr | -1 =>
306
+ pipe(
307
+ array.findLastIndex(
308
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
309
+ predicate as (value: E, index: number) => boolean,
310
+ ),
311
+ ).map((idx) => (idx >= 0 ? asUint32(idx) : -1)).value;
312
+
321
313
  /**
322
314
  * Gets the index of a value in an array.
323
315
  *
@@ -357,22 +349,23 @@ export function indexOf<E>(
357
349
  | readonly [searchElement: E]
358
350
  ): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr | -1) | -1 {
359
351
  switch (args.length) {
360
- case 2: {
361
- const [array, searchElement] = args;
362
-
363
- const index = array.indexOf(searchElement);
364
-
365
- return index !== -1 ? asUint32(index) : -1;
366
- }
352
+ case 2:
353
+ return indexOfImpl(...args);
367
354
 
368
- case 1: {
369
- const [searchElement] = args;
370
-
371
- return (array) => indexOf(array, searchElement);
372
- }
355
+ case 1:
356
+ return (array) => indexOfImpl(array, ...args);
373
357
  }
374
358
  }
375
359
 
360
+ const indexOfImpl = <E,>(
361
+ array: readonly E[],
362
+ searchElement: E,
363
+ ): SizeType.Arr | -1 => {
364
+ const index = array.indexOf(searchElement);
365
+
366
+ return index !== -1 ? asUint32(index) : -1;
367
+ };
368
+
376
369
  /**
377
370
  * Gets the index of a value in an array, starting from a specified index.
378
371
  *
@@ -425,22 +418,24 @@ export function indexOfFrom<E>(
425
418
  | readonly [searchElement: E, fromIndex: SizeType.ArgArrWithNegative]
426
419
  ): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr | -1) | -1 {
427
420
  switch (args.length) {
428
- case 3: {
429
- const [array, searchElement, fromIndex] = args;
421
+ case 3:
422
+ return indexOfFromImpl(...args);
430
423
 
431
- const index = array.indexOf(searchElement, fromIndex);
432
-
433
- return index !== -1 ? asUint32(index) : -1;
434
- }
435
-
436
- case 2: {
437
- const [searchElement, fromIndex] = args;
438
-
439
- return (array) => indexOfFrom(array, searchElement, fromIndex);
440
- }
424
+ case 2:
425
+ return (array) => indexOfFromImpl(array, ...args);
441
426
  }
442
427
  }
443
428
 
429
+ const indexOfFromImpl = <E,>(
430
+ array: readonly E[],
431
+ searchElement: E,
432
+ fromIndex: SizeType.ArgArrWithNegative,
433
+ ): SizeType.Arr | -1 => {
434
+ const index = array.indexOf(searchElement, fromIndex);
435
+
436
+ return index !== -1 ? asUint32(index) : -1;
437
+ };
438
+
444
439
  /**
445
440
  * Gets the last index of a value in an array.
446
441
  *
@@ -484,22 +479,23 @@ export function lastIndexOf<E>(
484
479
  | readonly [searchElement: E]
485
480
  ): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr | -1) | -1 {
486
481
  switch (args.length) {
487
- case 2: {
488
- const [array, searchElement] = args;
489
-
490
- const index = array.lastIndexOf(searchElement);
482
+ case 2:
483
+ return lastIndexOfImpl(...args);
491
484
 
492
- return index !== -1 ? asUint32(index) : -1;
493
- }
494
-
495
- case 1: {
496
- const [searchElement] = args;
497
-
498
- return (array) => lastIndexOf(array, searchElement);
499
- }
485
+ case 1:
486
+ return (array) => lastIndexOfImpl(array, ...args);
500
487
  }
501
488
  }
502
489
 
490
+ const lastIndexOfImpl = <E,>(
491
+ array: readonly E[],
492
+ searchElement: E,
493
+ ): SizeType.Arr | -1 => {
494
+ const index = array.lastIndexOf(searchElement);
495
+
496
+ return index !== -1 ? asUint32(index) : -1;
497
+ };
498
+
503
499
  /**
504
500
  * Gets the last index of a value in an array, starting from a specified index.
505
501
  *
@@ -552,18 +548,20 @@ export function lastIndexOfFrom<E>(
552
548
  | readonly [searchElement: E, fromIndex: SizeType.ArgArrWithNegative]
553
549
  ): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr | -1) | -1 {
554
550
  switch (args.length) {
555
- case 3: {
556
- const [array, searchElement, fromIndex] = args;
557
-
558
- const index = array.lastIndexOf(searchElement, fromIndex);
559
-
560
- return index !== -1 ? asUint32(index) : -1;
561
- }
562
-
563
- case 2: {
564
- const [searchElement, fromIndex] = args;
551
+ case 3:
552
+ return lastIndexOfFromImpl(...args);
565
553
 
566
- return (array) => lastIndexOfFrom(array, searchElement, fromIndex);
567
- }
554
+ case 2:
555
+ return (array) => lastIndexOfFromImpl(array, ...args);
568
556
  }
569
557
  }
558
+
559
+ const lastIndexOfFromImpl = <E,>(
560
+ array: readonly E[],
561
+ searchElement: E,
562
+ fromIndex: SizeType.ArgArrWithNegative,
563
+ ): SizeType.Arr | -1 => {
564
+ const index = array.lastIndexOf(searchElement, fromIndex);
565
+
566
+ return index !== -1 ? asUint32(index) : -1;
567
+ };
@@ -39,21 +39,23 @@ export function sliceClamped<E>(
39
39
  | readonly [SizeType.ArgArrWithNegative, SizeType.ArgArrWithNegative]
40
40
  ): readonly E[] | ((array: readonly E[]) => readonly E[]) {
41
41
  switch (args.length) {
42
- case 3: {
43
- const [array, start, end] = args;
42
+ case 3:
43
+ return sliceClampedImpl(...args);
44
44
 
45
- const startClamped = Num.clamp(0, array.length)(start);
46
-
47
- // Ensure endClamped is not less than startClamped.
48
- const endClamped = Num.clamp(startClamped, array.length)(end);
45
+ case 2:
46
+ return (array) => sliceClampedImpl(array, ...args);
47
+ }
48
+ }
49
49
 
50
- return array.slice(startClamped, endClamped);
51
- }
50
+ const sliceClampedImpl = <E,>(
51
+ array: readonly E[],
52
+ start: SizeType.ArgArrWithNegative,
53
+ end: SizeType.ArgArrWithNegative,
54
+ ): readonly E[] => {
55
+ const startClamped = Num.clamp(0, array.length)(start);
52
56
 
53
- case 2: {
54
- const [start, end] = args;
57
+ // Ensure endClamped is not less than startClamped.
58
+ const endClamped = Num.clamp(startClamped, array.length)(end);
55
59
 
56
- return (array) => sliceClamped(array, start, end);
57
- }
58
- }
59
- }
60
+ return array.slice(startClamped, endClamped);
61
+ };
@@ -115,20 +115,19 @@ export function take<E>(
115
115
  | readonly [num: SizeType.ArgArr]
116
116
  ): readonly E[] | ((array: readonly E[]) => readonly E[]) {
117
117
  switch (args.length) {
118
- case 2: {
119
- const [array, num] = args;
118
+ case 2:
119
+ return takeImpl(...args);
120
120
 
121
- return sliceClamped(array, 0, num);
122
- }
123
-
124
- case 1: {
125
- const [num] = args;
126
-
127
- return (array) => take(array, num);
128
- }
121
+ case 1:
122
+ return (array) => takeImpl(array, ...args);
129
123
  }
130
124
  }
131
125
 
126
+ const takeImpl = <E,>(
127
+ array: readonly E[],
128
+ num: SizeType.ArgArr,
129
+ ): readonly E[] => sliceClamped(array, 0, num);
130
+
132
131
  /**
133
132
  * Takes the last N elements from an array.
134
133
  *
@@ -178,20 +177,20 @@ export function takeLast<E>(
178
177
  | readonly [num: SizeType.ArgArr]
179
178
  ): readonly E[] | ((array: readonly E[]) => readonly E[]) {
180
179
  switch (args.length) {
181
- case 2: {
182
- const [array, num] = args;
180
+ case 2:
181
+ return takeLastImpl(...args);
183
182
 
184
- return sliceClamped(array, Uint32.sub(size(array), num), size(array));
185
- }
186
-
187
- case 1: {
188
- const [num] = args;
189
-
190
- return (array) => takeLast(array, num);
191
- }
183
+ case 1:
184
+ return (array) => takeLastImpl(array, ...args);
192
185
  }
193
186
  }
194
187
 
188
+ const takeLastImpl = <E,>(
189
+ array: readonly E[],
190
+ num: SizeType.ArgArr,
191
+ ): readonly E[] =>
192
+ sliceClamped(array, Uint32.sub(size(array), num), size(array));
193
+
195
194
  /**
196
195
  * Skips the first N elements of an array.
197
196
  *
@@ -230,20 +229,19 @@ export function skip<E>(
230
229
  ...args: readonly [readonly E[], SizeType.ArgArr] | readonly [SizeType.ArgArr]
231
230
  ): readonly E[] | ((array: readonly E[]) => readonly E[]) {
232
231
  switch (args.length) {
233
- case 2: {
234
- const [array, num] = args;
232
+ case 2:
233
+ return skipImpl(...args);
235
234
 
236
- return sliceClamped(array, num, size(array));
237
- }
238
-
239
- case 1: {
240
- const [num] = args;
241
-
242
- return (array) => skip(array, num);
243
- }
235
+ case 1:
236
+ return (array) => skipImpl(array, ...args);
244
237
  }
245
238
  }
246
239
 
240
+ const skipImpl = <E,>(
241
+ array: readonly E[],
242
+ num: SizeType.ArgArr,
243
+ ): readonly E[] => sliceClamped(array, num, size(array));
244
+
247
245
  /**
248
246
  * Skips the last N elements of an array.
249
247
  *
@@ -286,20 +284,19 @@ export function skipLast<E>(
286
284
  | readonly [num: SizeType.ArgArr]
287
285
  ): readonly E[] | ((array: readonly E[]) => readonly E[]) {
288
286
  switch (args.length) {
289
- case 2: {
290
- const [array, num] = args;
287
+ case 2:
288
+ return skipLastImpl(...args);
291
289
 
292
- return sliceClamped(array, 0, Uint32.sub(size(array), num));
293
- }
294
-
295
- case 1: {
296
- const [num] = args;
297
-
298
- return (array) => skipLast(array, num);
299
- }
290
+ case 1:
291
+ return (array) => skipLastImpl(array, ...args);
300
292
  }
301
293
  }
302
294
 
295
+ const skipLastImpl = <E,>(
296
+ array: readonly E[],
297
+ num: SizeType.ArgArr,
298
+ ): readonly E[] => sliceClamped(array, 0, Uint32.sub(size(array), num));
299
+
303
300
  /**
304
301
  * Alias for `tail`.
305
302
  *