utilitish 0.0.6 → 0.0.7
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/dist/array/array-constructor.js +5 -5
- package/dist/array/array-constructor.spec.d.ts +2 -0
- package/dist/array/array-constructor.spec.js +130 -0
- package/dist/array/array-prototype.d.ts +341 -84
- package/dist/array/array-prototype.js +38 -53
- package/dist/array/array-prototype.spec.d.ts +1 -0
- package/dist/array/array-prototype.spec.js +536 -0
- package/dist/map/map-prototype.d.ts +69 -9
- package/dist/map/map-prototype.js +16 -3
- package/dist/map/map-prototype.spec.d.ts +1 -0
- package/dist/map/map-prototype.spec.js +261 -0
- package/dist/object/object-prototype.d.ts +61 -8
- package/dist/object/object-prototype.js +9 -0
- package/dist/object/object-prototype.spec.d.ts +1 -0
- package/dist/object/object-prototype.spec.js +110 -0
- package/dist/set/set-prototype.d.ts +83 -5
- package/dist/set/set-prototype.js +21 -6
- package/dist/set/set-prototype.spec.d.ts +1 -0
- package/dist/set/set-prototype.spec.js +122 -0
- package/dist/string/string-prototype.d.ts +143 -24
- package/dist/string/string-prototype.js +41 -11
- package/dist/string/string-prototype.spec.d.ts +1 -0
- package/dist/string/string-prototype.spec.js +115 -0
- package/dist/utils/logic.utils.d.ts +3 -0
- package/dist/utils/logic.utils.js +41 -0
- package/package.json +1 -1
- /package/dist/{utils.d.ts → utils/core.utils.d.ts} +0 -0
- /package/dist/{utils.js → utils/core.utils.js} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
3
|
+
const core_utils_1 = require("../utils/core.utils");
|
|
4
4
|
/**
|
|
5
5
|
* @see Array.zip
|
|
6
6
|
*/
|
|
7
|
-
(0,
|
|
7
|
+
(0, core_utils_1.defineStaticIfNotExists)(Array, 'zip', function (...arrays) {
|
|
8
8
|
if (arrays.length === 0)
|
|
9
9
|
return [];
|
|
10
10
|
const maxLen = Math.max(...arrays.map((arr) => arr.length));
|
|
@@ -13,7 +13,7 @@ const utils_1 = require("../utils");
|
|
|
13
13
|
/**
|
|
14
14
|
* @see Array.range
|
|
15
15
|
*/
|
|
16
|
-
(0,
|
|
16
|
+
(0, core_utils_1.defineStaticIfNotExists)(Array, 'range', function (start, end, step = 1) {
|
|
17
17
|
if (end === undefined) {
|
|
18
18
|
end = start;
|
|
19
19
|
start = 0;
|
|
@@ -30,7 +30,7 @@ const utils_1 = require("../utils");
|
|
|
30
30
|
/**
|
|
31
31
|
* @see Array.repeat
|
|
32
32
|
*/
|
|
33
|
-
(0,
|
|
33
|
+
(0, core_utils_1.defineStaticIfNotExists)(Array, 'repeat', function (length, value) {
|
|
34
34
|
if (typeof length !== 'number' || !Number.isInteger(length) || length < 0) {
|
|
35
35
|
throw new TypeError('Length must be a non-negative integer');
|
|
36
36
|
}
|
|
@@ -39,7 +39,7 @@ const utils_1 = require("../utils");
|
|
|
39
39
|
/**
|
|
40
40
|
* @see Array.create
|
|
41
41
|
*/
|
|
42
|
-
(0,
|
|
42
|
+
(0, core_utils_1.defineStaticIfNotExists)(Array, 'create', function (valueOrFactory, ...sizes) {
|
|
43
43
|
if (sizes.length === 0)
|
|
44
44
|
return [];
|
|
45
45
|
if (!sizes.every((s) => Number.isInteger(s) && s >= 0)) {
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
require("../array/array-constructor");
|
|
4
|
+
require("./array-constructor");
|
|
5
|
+
describe('Array', () => {
|
|
6
|
+
describe('range()', () => {
|
|
7
|
+
it('should generate a range from 0 to n-1 if only start is given', () => {
|
|
8
|
+
expect(Array.range(5)).toEqual([0, 1, 2, 3, 4]);
|
|
9
|
+
});
|
|
10
|
+
it('should generate a range from start to end-1', () => {
|
|
11
|
+
expect(Array.range(2, 6)).toEqual([2, 3, 4, 5]);
|
|
12
|
+
});
|
|
13
|
+
it('should support negative steps', () => {
|
|
14
|
+
expect(Array.range(5, 1, -1)).toEqual([5, 4, 3, 2]);
|
|
15
|
+
});
|
|
16
|
+
it('should return an empty array if start equals end', () => {
|
|
17
|
+
expect(Array.range(3, 3)).toEqual([]);
|
|
18
|
+
});
|
|
19
|
+
it('should return an empty array if step does not reach end', () => {
|
|
20
|
+
expect(Array.range(0, 5, -1)).toEqual([]);
|
|
21
|
+
expect(Array.range(5, 0, 1)).toEqual([]);
|
|
22
|
+
});
|
|
23
|
+
describe('error handling', () => {
|
|
24
|
+
it('should throw if step is 0', () => {
|
|
25
|
+
expect(() => Array.range(0, 5, 0)).toThrowError('step must not be 0');
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe('repeat()', () => {
|
|
30
|
+
it('should fill an array with the same value', () => {
|
|
31
|
+
expect(Array.repeat(3, 'a')).toEqual(['a', 'a', 'a']);
|
|
32
|
+
});
|
|
33
|
+
it('should fill an array with values from a function', () => {
|
|
34
|
+
let n = 0;
|
|
35
|
+
expect(Array.repeat(4, () => ++n)).toEqual([1, 2, 3, 4]);
|
|
36
|
+
});
|
|
37
|
+
it('should return an empty array if length is 0', () => {
|
|
38
|
+
expect(Array.repeat(0, 'x')).toEqual([]);
|
|
39
|
+
});
|
|
40
|
+
describe('error handling', () => {
|
|
41
|
+
it('should throw if length is negative or not an integer', () => {
|
|
42
|
+
expect(() => Array.repeat(-1, 'a')).toThrowError();
|
|
43
|
+
expect(() => Array.repeat(1.5, 'a')).toThrowError();
|
|
44
|
+
expect(() => Array.repeat('a', 'a')).toThrowError();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
describe('zip()', () => {
|
|
49
|
+
it('should zip two arrays of equal length', () => {
|
|
50
|
+
expect(Array.zip([1, 2, 3], ['a', 'b', 'c'])).toEqual([
|
|
51
|
+
[1, 'a'],
|
|
52
|
+
[2, 'b'],
|
|
53
|
+
[3, 'c'],
|
|
54
|
+
]);
|
|
55
|
+
});
|
|
56
|
+
it('should zip arrays of different lengths (fill with undefined)', () => {
|
|
57
|
+
expect(Array.zip([1, 2], ['a', 'b', 'c'], [true, false, true])).toEqual([
|
|
58
|
+
[1, 'a', true],
|
|
59
|
+
[2, 'b', false],
|
|
60
|
+
[undefined, 'c', true],
|
|
61
|
+
]);
|
|
62
|
+
});
|
|
63
|
+
it('should work with a single array', () => {
|
|
64
|
+
expect(Array.zip([1, 2, 3])).toEqual([[1], [2], [3]]);
|
|
65
|
+
});
|
|
66
|
+
it('should fill with undefined for missing elements', () => {
|
|
67
|
+
expect(Array.zip([1], [2, 3, 4])).toEqual([
|
|
68
|
+
[1, 2],
|
|
69
|
+
[undefined, 3],
|
|
70
|
+
[undefined, 4],
|
|
71
|
+
]);
|
|
72
|
+
});
|
|
73
|
+
describe('edge cases', () => {
|
|
74
|
+
it('should return an empty array if no arrays are given', () => {
|
|
75
|
+
expect(Array.zip()).toEqual([]);
|
|
76
|
+
});
|
|
77
|
+
it('should return an array of undefined if all arrays are empty', () => {
|
|
78
|
+
expect(Array.zip([], [])).toEqual([]);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe('create()', () => {
|
|
83
|
+
it('should create a 1D array', () => {
|
|
84
|
+
expect(Array.create('x', 3)).toEqual(['x', 'x', 'x']);
|
|
85
|
+
});
|
|
86
|
+
it('should create a 2D array', () => {
|
|
87
|
+
expect(Array.create(0, 2, 3)).toEqual([
|
|
88
|
+
[0, 0, 0],
|
|
89
|
+
[0, 0, 0],
|
|
90
|
+
]);
|
|
91
|
+
});
|
|
92
|
+
it('should create a 3D array', () => {
|
|
93
|
+
expect(Array.create(true, 2, 2, 2)).toEqual([
|
|
94
|
+
[
|
|
95
|
+
[true, true],
|
|
96
|
+
[true, true],
|
|
97
|
+
],
|
|
98
|
+
[
|
|
99
|
+
[true, true],
|
|
100
|
+
[true, true],
|
|
101
|
+
],
|
|
102
|
+
]);
|
|
103
|
+
});
|
|
104
|
+
describe('edge cases', () => {
|
|
105
|
+
it('should return [] if no sizes are given', () => {
|
|
106
|
+
expect(Array.create('x')).toEqual([]);
|
|
107
|
+
});
|
|
108
|
+
it('should return [] if any size is 0', () => {
|
|
109
|
+
expect(Array.create('x', 0)).toEqual([]);
|
|
110
|
+
expect(Array.create('x', 2, 0)).toEqual([[], []]);
|
|
111
|
+
});
|
|
112
|
+
it('should return arrays with the same object reference for objects', () => {
|
|
113
|
+
const obj = { a: 1 };
|
|
114
|
+
const arr = Array.create(obj, 2);
|
|
115
|
+
expect(arr[0]).toBe(obj);
|
|
116
|
+
expect(arr[1]).toBe(obj);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe('error handling', () => {
|
|
120
|
+
it('should throw if a size is negative', () => {
|
|
121
|
+
expect(() => Array.create('x', -1)).toThrow(TypeError);
|
|
122
|
+
expect(() => Array.create('x', 2, -3)).toThrow(TypeError);
|
|
123
|
+
});
|
|
124
|
+
it('should throw if a size is not an integer', () => {
|
|
125
|
+
expect(() => Array.create('x', 2.5)).toThrow(TypeError);
|
|
126
|
+
expect(() => Array.create('x', 2, 1.1)).toThrow(TypeError);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
@@ -1,132 +1,389 @@
|
|
|
1
|
+
import { Selector } from '../utils/core.utils';
|
|
1
2
|
export {};
|
|
2
3
|
declare global {
|
|
3
4
|
interface Array<T> {
|
|
4
5
|
/**
|
|
5
6
|
* Returns the first element of the array, or `undefined` if the array is empty.
|
|
7
|
+
*
|
|
8
|
+
* @template T The type of array elements
|
|
9
|
+
* @this {T[]} The array to get the first element from
|
|
10
|
+
* @returns {T | undefined} The first element or undefined if the array is empty
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* [1, 2, 3].first(); // 1
|
|
14
|
+
* [].first(); // undefined
|
|
6
15
|
*/
|
|
7
16
|
first(): T | undefined;
|
|
8
17
|
/**
|
|
9
18
|
* Returns the last element of the array, or `undefined` if the array is empty.
|
|
19
|
+
*
|
|
20
|
+
* @template T The type of array elements
|
|
21
|
+
* @this {T[]} The array to get the last element from
|
|
22
|
+
* @returns {T | undefined} The last element or undefined if the array is empty
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* [1, 2, 3].last(); // 3
|
|
26
|
+
* [].last(); // undefined
|
|
10
27
|
*/
|
|
11
28
|
last(): T | undefined;
|
|
12
29
|
/**
|
|
13
30
|
* Calculates the sum of the array values.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
31
|
+
* Supports bare number arrays or objects with a selector to extract numeric values.
|
|
32
|
+
*
|
|
33
|
+
* @template T The type of array elements
|
|
34
|
+
* @this {number[]|T[]} The array to sum
|
|
35
|
+
* @param {Selector<T, number>} [selector] - Optional function or property key to extract numbers
|
|
36
|
+
* @returns {number} The sum of all values (0 for empty arrays)
|
|
37
|
+
* @throws {TypeError} If array is not of type number[] and no selector is provided
|
|
16
38
|
*
|
|
17
|
-
* @
|
|
18
|
-
*
|
|
19
|
-
*
|
|
39
|
+
* @example
|
|
40
|
+
* [1, 2, 3].sum(); // 6
|
|
41
|
+
* [].sum(); // 0
|
|
42
|
+
* [{ x: 1 }, { x: 2 }].sum(x => x.x); // 3
|
|
43
|
+
* [{ x: 1 }, { x: 2 }].sum('x'); // 3
|
|
44
|
+
*
|
|
45
|
+
* @remarks
|
|
46
|
+
* - For number arrays, no selector is required
|
|
47
|
+
* - For object arrays, use property key string or callback function
|
|
48
|
+
* - Returns 0 for empty arrays regardless of type
|
|
20
49
|
*/
|
|
21
50
|
sum(this: number[]): number;
|
|
22
|
-
sum
|
|
23
|
-
sum(this: T[], callback: (item: T) => number): number;
|
|
51
|
+
sum(this: T[], selector?: Selector<T, number>): number;
|
|
24
52
|
/**
|
|
25
|
-
* Returns a new array with only unique elements
|
|
53
|
+
* Returns a new array with only unique elements based on strict equality (===).
|
|
54
|
+
* Preserves order of first occurrence.
|
|
55
|
+
*
|
|
56
|
+
* @template T The type of array elements
|
|
57
|
+
* @this {T[]} The array to filter
|
|
58
|
+
* @returns {T[]} A new array with duplicate values removed
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* [1, 1, 2, 2, 3].unique(); // [1, 2, 3]
|
|
62
|
+
* [{id: 1}, {id: 1}, {id: 2}].unique(); // [{id: 1}, {id: 1}, {id: 2}] (objects compared by reference)
|
|
63
|
+
*
|
|
64
|
+
* @remarks
|
|
65
|
+
* - Uses Set internally for efficiency
|
|
66
|
+
* - Only removes duplicates based on strict equality
|
|
67
|
+
* - For object arrays, same reference is considered equal
|
|
26
68
|
*/
|
|
27
69
|
unique(): T[];
|
|
28
70
|
/**
|
|
29
|
-
* Splits the array into chunks of
|
|
30
|
-
*
|
|
71
|
+
* Splits the array into chunks (sub-arrays) of a specified maximum size.
|
|
72
|
+
*
|
|
73
|
+
* @template T The type of array elements
|
|
74
|
+
* @this {T[]} The array to chunk
|
|
75
|
+
* @param {number} size - Maximum size of each chunk (must be positive integer)
|
|
76
|
+
* @returns {T[][]} A new array of chunks, where each chunk has at most `size` elements
|
|
77
|
+
* @throws {TypeError} If size is not a positive integer
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* [1, 2, 3, 4].chunk(2); // [[1, 2], [3, 4]]
|
|
81
|
+
* [1, 2, 3].chunk(2); // [[1, 2], [3]]
|
|
82
|
+
* [1, 2, 3, 4, 5].chunk(2); // [[1, 2], [3, 4], [5]]
|
|
83
|
+
*
|
|
84
|
+
* @remarks
|
|
85
|
+
* - Last chunk may have fewer elements if array length is not divisible by size
|
|
86
|
+
* - Empty array returns an empty array
|
|
31
87
|
*/
|
|
32
88
|
chunk(size: number): T[][];
|
|
33
89
|
/**
|
|
34
|
-
* Calculates the average of the array values.
|
|
35
|
-
*
|
|
36
|
-
*
|
|
90
|
+
* Calculates the average (mean) of the array values.
|
|
91
|
+
* Supports bare number arrays or objects with a selector to extract numeric values.
|
|
92
|
+
*
|
|
93
|
+
* @template T The type of array elements
|
|
94
|
+
* @this {number[]|T[]} The array to average
|
|
95
|
+
* @param {Selector<T, number>} [selector] - Optional function or property key to extract numbers
|
|
96
|
+
* @returns {number} The average of all values (0 for empty arrays)
|
|
97
|
+
* @throws {TypeError} If array is not of type number[] and no selector is provided
|
|
37
98
|
*
|
|
38
|
-
* @
|
|
39
|
-
*
|
|
40
|
-
*
|
|
99
|
+
* @example
|
|
100
|
+
* [2, 4, 6].average(); // 4
|
|
101
|
+
* [].average(); // 0
|
|
102
|
+
* [{x: 2}, {x: 4}].average(x => x.x); // 3
|
|
103
|
+
* [{x: 2}, {x: 4}].average('x'); // 3
|
|
104
|
+
*
|
|
105
|
+
* @remarks
|
|
106
|
+
* - For number arrays, no selector is required
|
|
107
|
+
* - Returns 0 for empty arrays (prevents division by zero)
|
|
108
|
+
* - For object arrays, use property key string or callback function
|
|
41
109
|
*/
|
|
42
110
|
average(this: number[]): number;
|
|
43
|
-
average
|
|
44
|
-
average(this: T[], callback: (item: T) => number): number;
|
|
111
|
+
average(this: T[], selector: Selector<T, number>): number;
|
|
45
112
|
/**
|
|
46
|
-
* Groups
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* @
|
|
113
|
+
* Groups array elements into a Map based on a key returned by the selector.
|
|
114
|
+
* Elements with the same key are grouped together in an array.
|
|
115
|
+
*
|
|
116
|
+
* @template T The type of array elements
|
|
117
|
+
* @template K The type of grouping key (extracted from selector)
|
|
118
|
+
* @this {T[]} The array to group
|
|
119
|
+
* @param {Selector<T, K>} selector - Function or property key to extract the grouping key
|
|
120
|
+
* @returns {Map<K, T[]>} A Map where keys map to arrays of grouped items
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* const arr = [{type: 'a', v: 1}, {type: 'b', v: 2}, {type: 'a', v: 3}];
|
|
124
|
+
* arr.groupBy('type');
|
|
125
|
+
* // Map { 'a' => [{type: 'a', v: 1}, {type: 'a', v: 3}], 'b' => [{type: 'b', v: 2}] }
|
|
126
|
+
*
|
|
127
|
+
* arr.groupBy(x => x.v % 2);
|
|
128
|
+
* // Map { 1 => [{type: 'a', v: 1}, {type: 'a', v: 3}], 0 => [{type: 'b', v: 2}] }
|
|
129
|
+
*
|
|
130
|
+
* @remarks
|
|
131
|
+
* - Order of groups in Map matches insertion order (first occurrence of key)
|
|
132
|
+
* - Empty array returns an empty Map
|
|
50
133
|
*/
|
|
51
|
-
groupBy<K
|
|
52
|
-
groupBy<K>(this: T[], selector: (item: T) => K): Map<K, T[]>;
|
|
134
|
+
groupBy<K>(this: T[], selector: Selector<T, K>): Map<K, T[]>;
|
|
53
135
|
/**
|
|
54
|
-
* Removes all falsy values
|
|
55
|
-
*
|
|
136
|
+
* Removes all falsy values from the array.
|
|
137
|
+
* Removes: `false`, `null`, `0`, `""` (empty string), `undefined`, `NaN`.
|
|
138
|
+
*
|
|
139
|
+
* @template T The type of array elements
|
|
140
|
+
* @this {T[]} The array to compact
|
|
141
|
+
* @returns {T[]} A new array with all falsy values removed
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* [0, 1, false, 2, '', 3, null, undefined, NaN].compact();
|
|
145
|
+
* // [1, 2, 3]
|
|
146
|
+
*
|
|
147
|
+
* @remarks
|
|
148
|
+
* - Uses JavaScript's falsy value definition
|
|
149
|
+
* - Returns a new array (original is not modified)
|
|
56
150
|
*/
|
|
57
151
|
compact(): T[];
|
|
58
152
|
/**
|
|
59
|
-
* Enumerates the array into tuples [value, index].
|
|
153
|
+
* Enumerates the array into tuples of [value, index].
|
|
60
154
|
* Similar to Python's enumerate but returns value first.
|
|
61
|
-
*
|
|
155
|
+
*
|
|
156
|
+
* @template T The type of array elements
|
|
157
|
+
* @this {T[]} The array to enumerate
|
|
158
|
+
* @returns {[T, number][]} An array of [value, index] tuples
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ['a', 'b', 'c'].enumerate();
|
|
162
|
+
* // [['a', 0], ['b', 1], ['c', 2]]
|
|
163
|
+
*
|
|
164
|
+
* @remarks
|
|
165
|
+
* - Value comes first (before index), unlike JavaScript's map callback
|
|
166
|
+
* - Index is always the enumeration index (0-based)
|
|
62
167
|
*/
|
|
63
168
|
enumerate(): [T, number][];
|
|
64
169
|
/**
|
|
65
|
-
* Returns a sorted copy of the array in ascending order.
|
|
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
|
-
*
|
|
170
|
+
* Returns a new sorted copy of the array in ascending order.
|
|
171
|
+
* Creates a new array without modifying the original.
|
|
172
|
+
*
|
|
173
|
+
* @template T The type of array elements
|
|
174
|
+
* @this {number[]|string[]|T[]} The array to sort
|
|
175
|
+
* @param {Selector<T, number|string>} [selector] - Optional function or property key to extract sortable value
|
|
176
|
+
* @returns {T[]} A new array sorted in ascending order
|
|
177
|
+
* @throws {TypeError} If elements are not sortable or selector returns invalid type
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* [3, 1, 2].sortAsc(); // [1, 2, 3]
|
|
181
|
+
* ['c', 'a', 'b'].sortAsc(); // ['a', 'b', 'c']
|
|
182
|
+
* [{v: 2}, {v: 1}].sortAsc(x => x.v); // [{v: 1}, {v: 2}]
|
|
183
|
+
* [{v: 2}, {v: 1}].sortAsc('v'); // [{v: 1}, {v: 2}]
|
|
184
|
+
*
|
|
185
|
+
* @remarks
|
|
186
|
+
* - For primitive arrays, no selector needed (must be number or string)
|
|
187
|
+
* - Selectors must return number or string for comparison
|
|
188
|
+
* - Returns new array; does not mutate original
|
|
189
|
+
* - Empty arrays return empty array
|
|
190
|
+
*/
|
|
191
|
+
sortAsc(this: T[], selector?: Selector<T, number | string>): T[];
|
|
192
|
+
/**
|
|
193
|
+
* Returns a new sorted copy of the array in descending order.
|
|
194
|
+
* Creates a new array without modifying the original.
|
|
195
|
+
*
|
|
196
|
+
* @template T The type of array elements
|
|
197
|
+
* @this {number[]|string[]|T[]} The array to sort
|
|
198
|
+
* @param {Selector<T, number|string>} [selector] - Optional function or property key to extract sortable value
|
|
199
|
+
* @returns {T[]} A new array sorted in descending order
|
|
200
|
+
* @throws {TypeError} If elements are not sortable or selector returns invalid type
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* [1, 3, 2].sortDesc(); // [3, 2, 1]
|
|
204
|
+
* ['a', 'c', 'b'].sortDesc(); // ['c', 'b', 'a']
|
|
205
|
+
* [{v: 1}, {v: 2}].sortDesc(x => x.v); // [{v: 2}, {v: 1}]
|
|
206
|
+
* [{v: 1}, {v: 2}].sortDesc('v'); // [{v: 2}, {v: 1}]
|
|
207
|
+
*
|
|
208
|
+
* @remarks
|
|
209
|
+
* - For primitive arrays, no selector needed (must be number or string)
|
|
210
|
+
* - Selectors must return number or string for comparison
|
|
211
|
+
* - Returns new array; does not mutate original
|
|
212
|
+
* - Empty arrays return empty array
|
|
213
|
+
*/
|
|
214
|
+
sortDesc(this: T[], selector?: Selector<T, number | string>): T[];
|
|
215
|
+
/**
|
|
216
|
+
* Swaps the elements at two indices within the array.
|
|
217
|
+
* Modifies the array in place and returns the array itself (for chaining).
|
|
218
|
+
*
|
|
219
|
+
* @template T The type of array elements
|
|
220
|
+
* @this {T[]} The array to modify
|
|
221
|
+
* @param {number} i - First index to swap
|
|
222
|
+
* @param {number} j - Second index to swap
|
|
223
|
+
* @returns {T[]} The modified array (same reference as this)
|
|
224
|
+
* @throws {TypeError} If indices are not integers
|
|
225
|
+
* @throws {RangeError} If any index is out of bounds (negative or >= length)
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* const arr = [1, 2, 3];
|
|
229
|
+
* arr.swap(0, 2); // arr is now [3, 2, 1]
|
|
230
|
+
* arr === arr.swap(0, 2); // true (returns same array)
|
|
231
|
+
*
|
|
232
|
+
* @remarks
|
|
233
|
+
* - Does nothing if i === j
|
|
234
|
+
* - Modifies original array (not immutable)
|
|
235
|
+
* - Validates both indices are valid integers
|
|
91
236
|
*/
|
|
92
237
|
swap(i: number, j: number): this;
|
|
93
238
|
/**
|
|
94
|
-
* Returns a new array with
|
|
95
|
-
* Uses
|
|
96
|
-
*
|
|
239
|
+
* Returns a new array with elements shuffled randomly.
|
|
240
|
+
* Uses Fisher-Yates algorithm for uniform distribution.
|
|
241
|
+
* Does not modify the original array.
|
|
242
|
+
*
|
|
243
|
+
* @template T The type of array elements
|
|
244
|
+
* @this {T[]} The array to shuffle
|
|
245
|
+
* @returns {T[]} A new shuffled array
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* const arr = [1, 2, 3, 4, 5];
|
|
249
|
+
* const shuffled = arr.shuffle();
|
|
250
|
+
* // shuffled might be [3, 1, 5, 2, 4] (order is random)
|
|
251
|
+
* arr; // [1, 2, 3, 4, 5] (unchanged)
|
|
252
|
+
*
|
|
253
|
+
* @remarks
|
|
254
|
+
* - Returns new array instance (original unchanged)
|
|
255
|
+
* - Uses Math.random() so results vary
|
|
256
|
+
* - Empty arrays return empty array
|
|
257
|
+
* - Fisher-Yates algorithm ensures unbiased distribution
|
|
97
258
|
*/
|
|
98
259
|
shuffle(): T[];
|
|
99
260
|
/**
|
|
100
|
-
* Converts an array to a Map.
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* @
|
|
105
|
-
* @
|
|
261
|
+
* Converts an array to a Map using keys and optionally values extracted from elements.
|
|
262
|
+
* Supports multiple input formats: pairs array, property key, or selector functions.
|
|
263
|
+
*
|
|
264
|
+
* @template T The type of array elements
|
|
265
|
+
* @template K The type of Map keys
|
|
266
|
+
* @template V The type of Map values
|
|
267
|
+
* @this {[K, V][]|T[]} The array to convert
|
|
268
|
+
* @param {K | (item: T) => K} [keySelector] - Property key or function to extract keys
|
|
269
|
+
* @param {(item: T) => V} [valueSelector] - Optional function to extract values
|
|
270
|
+
* @returns {Map<K, V>} A Map with extracted key-value pairs
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* // From pairs
|
|
274
|
+
* [['a', 1], ['b', 2]].toMap(); // Map { 'a' => 1, 'b' => 2 }
|
|
275
|
+
*
|
|
276
|
+
* // Using property key
|
|
277
|
+
* [{id: 1, name: 'foo'}, {id: 2, name: 'bar'}].toMap('id');
|
|
278
|
+
* // Map { 1 => {id: 1, name: 'foo'}, 2 => {id: 2, name: 'bar'} }
|
|
279
|
+
*
|
|
280
|
+
* // Using selectors
|
|
281
|
+
* [{id: 1, name: 'foo'}].toMap(x => x.id, x => x.name);
|
|
282
|
+
* // Map { 1 => 'foo' }
|
|
283
|
+
*
|
|
284
|
+
* // Default (uses index)
|
|
285
|
+
* ['a', 'b'].toMap();
|
|
286
|
+
* // Map { 0 => 'a', 1 => 'b' }
|
|
287
|
+
*
|
|
288
|
+
* @remarks
|
|
289
|
+
* - For pairs array, no parameters needed
|
|
290
|
+
* - For objects, provide key as string or selector function
|
|
291
|
+
* - Value defaults to the entire element if not specified
|
|
292
|
+
* - Index is used as key if no keySelector provided
|
|
106
293
|
*/
|
|
107
294
|
toMap<K, V>(this: [K, V][]): Map<K, V>;
|
|
108
|
-
toMap<K
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
295
|
+
toMap<K, V>(this: T[], keySelector?: Selector<T, K>, valueSelector?: Selector<T, V>): Map<K | number, V | T>;
|
|
296
|
+
/**
|
|
297
|
+
* Converts an array to a plain JavaScript object using keys and optionally values extracted from elements.
|
|
298
|
+
* Leverages Map.prototype.toObject() internally for consistency and validation.
|
|
299
|
+
*
|
|
300
|
+
* @template T The type of array elements
|
|
301
|
+
* @template K Type of object keys (must be PropertyKey: string | number)
|
|
302
|
+
* @template V Type of object values
|
|
303
|
+
* @this {[K, V][]|T[]} The array to convert
|
|
304
|
+
* @param {K | keyof T | (item: T) => K} [keySelector] - Property key or function to extract keys
|
|
305
|
+
* @param {(item: T) => V} [valueSelector] - Optional function to extract values
|
|
306
|
+
* @returns {Record<K, V>} A plain object with array elements as properties
|
|
307
|
+
* @throws {TypeError} If any key is null, undefined, or not a valid PropertyKey (string/number)
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* // From pairs
|
|
311
|
+
* [['a', 1], ['b', 2]].toObject(); // { a: 1, b: 2 }
|
|
312
|
+
*
|
|
313
|
+
* // Using property key
|
|
314
|
+
* [{id: 1, name: 'foo'}, {id: 2, name: 'bar'}].toObject('id');
|
|
315
|
+
* // { 1: {id: 1, name: 'foo'}, 2: {id: 2, name: 'bar'} }
|
|
316
|
+
*
|
|
317
|
+
* // Using selectors
|
|
318
|
+
* [{id: 1, name: 'foo'}].toObject(x => x.id, x => x.name);
|
|
319
|
+
* // { 1: 'foo' }
|
|
320
|
+
*
|
|
321
|
+
* // Default (uses index)
|
|
322
|
+
* ['a', 'b'].toObject();
|
|
323
|
+
* // { 0: 'a', 1: 'b' }
|
|
324
|
+
*
|
|
325
|
+
* @remarks
|
|
326
|
+
* - For pairs array, no parameters needed
|
|
327
|
+
* - For objects, provide key as string or selector function
|
|
328
|
+
* - Value defaults to the entire element if not specified
|
|
329
|
+
* - Index is used as key if no keySelector provided
|
|
330
|
+
* - Validates keys are valid PropertyKeys (not null/undefined)
|
|
331
|
+
* - Symbols are not supported in plain objects
|
|
332
|
+
*/
|
|
333
|
+
toObject<K extends PropertyKey, V>(this: [K, V][]): Record<K, V>;
|
|
334
|
+
toObject<K extends PropertyKey, V>(this: T[], keySelector?: Selector<T, K>, valueSelector?: Selector<T, V>): Record<K | number, V | T>;
|
|
112
335
|
/**
|
|
113
336
|
* Returns a Set containing the unique elements of the array.
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* @
|
|
118
|
-
* @
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
337
|
+
* Optionally applies a selector function or property key to extract values for the Set.
|
|
338
|
+
*
|
|
339
|
+
* @template T The type of array elements
|
|
340
|
+
* @template K The type of selected values for the Set
|
|
341
|
+
* @this {T[]} The array to convert
|
|
342
|
+
* @param {Selector<T, K>} [selector] - Optional property key or function to select values
|
|
343
|
+
* @returns {Set<T | K>} A Set of unique elements or selected values
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* [1, 2, 2, 3].toSet(); // Set { 1, 2, 3 }
|
|
347
|
+
*
|
|
348
|
+
* [{id: 1}, {id: 2}, {id: 1}].toSet(x => x.id);
|
|
349
|
+
* // Set { 1, 2 }
|
|
350
|
+
*
|
|
351
|
+
* [{id: 1}, {id: 2}].toSet('id');
|
|
352
|
+
* // Set { 1, 2 }
|
|
353
|
+
*
|
|
354
|
+
* @remarks
|
|
355
|
+
* - Without selector, stores the entire element in the Set
|
|
356
|
+
* - With selector, stores the extracted value instead
|
|
357
|
+
* - Uses Set's built-in uniqueness (based on === equality)
|
|
358
|
+
* - Empty array returns empty Set
|
|
359
|
+
*/
|
|
360
|
+
toSet<K>(this: T[], selector?: Selector<T, K>): Set<T | K>;
|
|
361
|
+
/**
|
|
362
|
+
* Groups array elements by a key and counts the occurrences of each key.
|
|
363
|
+
* Returns a Map where keys map to their occurrence counts.
|
|
364
|
+
*
|
|
365
|
+
* @template T The type of array elements
|
|
366
|
+
* @template K The type of grouping key
|
|
367
|
+
* @this {T[]} The array to count
|
|
368
|
+
* @param {Selector<T, K>} [selector] - Optional property key or function to extract grouping key
|
|
369
|
+
* @returns {Map<T | K, number>} A Map where keys map to their occurrence counts
|
|
370
|
+
*
|
|
371
|
+
* @example
|
|
372
|
+
* ['a', 'b', 'a', 'c', 'b', 'a'].countBy();
|
|
373
|
+
* // Map { 'a' => 3, 'b' => 2, 'c' => 1 }
|
|
374
|
+
*
|
|
375
|
+
* [{type: 'x'}, {type: 'y'}, {type: 'x'}].countBy(x => x.type);
|
|
376
|
+
* // Map { 'x' => 2, 'y' => 1 }
|
|
377
|
+
*
|
|
378
|
+
* [{type: 'x'}, {type: 'y'}].countBy('type');
|
|
379
|
+
* // Map { 'x' => 1, 'y' => 1 }
|
|
380
|
+
*
|
|
381
|
+
* @remarks
|
|
382
|
+
* - Without selector, counts entire elements
|
|
383
|
+
* - With selector, counts extracted keys
|
|
384
|
+
* - Uses === equality for counting
|
|
385
|
+
* - Empty array returns empty Map
|
|
386
|
+
*/
|
|
387
|
+
countBy<K>(this: T[], selector?: Selector<T, K>): Map<T | K, number>;
|
|
131
388
|
}
|
|
132
389
|
}
|