atomic-fns 1.1.6 → 1.2.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/README.md +51 -12
- package/dist/collections/BTree.d.ts +11 -10
- package/dist/collections/BTree.js +58 -80
- package/dist/collections/Heap.d.ts +2 -2
- package/dist/collections/Heap.js +1 -1
- package/dist/collections/LRUCache.d.ts +8 -5
- package/dist/collections/LRUCache.js +24 -11
- package/dist/collections/SortedMap.d.ts +4 -4
- package/dist/collections/SortedMap.js +4 -3
- package/dist/collections/SortedSet.d.ts +2 -2
- package/dist/collections/SortedTree.d.ts +9 -9
- package/dist/collections/SortedTree.js +7 -6
- package/dist/collections/SplayTree.d.ts +17 -15
- package/dist/collections/SplayTree.js +42 -29
- package/dist/collections/Trie.d.ts +2 -2
- package/dist/collections/Trie.js +26 -26
- package/dist/collections/deque.d.ts +11 -11
- package/dist/collections/deque.js +17 -10
- package/dist/collections/frozenset.js +4 -1
- package/dist/collections/index.d.ts +30 -48
- package/dist/collections/index.js +210 -82
- package/dist/decimal/index.d.ts +7 -5
- package/dist/decimal/index.js +63 -28
- package/dist/functools/index.d.ts +10 -34
- package/dist/functools/index.js +25 -57
- package/dist/globals/index.d.ts +5 -22
- package/dist/globals/index.js +24 -40
- package/dist/i18n/currency.d.ts +10 -7
- package/dist/i18n/currency.js +22 -7
- package/dist/i18n/date/index.d.ts +22 -16
- package/dist/i18n/date/index.js +89 -67
- package/dist/i18n/date/utils.d.ts +6 -7
- package/dist/i18n/date/utils.js +15 -113
- package/dist/i18n/duration.d.ts +13 -12
- package/dist/i18n/duration.js +38 -32
- package/dist/i18n/format.d.ts +10 -2
- package/dist/i18n/format.js +100 -217
- package/dist/i18n/index.d.ts +2 -1
- package/dist/itertools/index.d.ts +21 -25
- package/dist/itertools/index.js +41 -44
- package/dist/math/index.d.ts +12 -29
- package/dist/math/index.js +16 -33
- package/dist/mod.d.ts +1 -0
- package/dist/mod.js +1 -0
- package/dist/operators/index.d.ts +3 -3
- package/dist/operators/index.js +62 -38
- package/dist/random/index.js +9 -6
- package/dist/string/index.d.ts +1 -1
- package/dist/string/index.js +2 -4
- package/dist/types.d.ts +3 -3
- package/package.json +16 -21
package/dist/itertools/index.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module itertools
|
|
5
5
|
*/
|
|
6
|
-
import { call, isEmpty, isObject, notNull, ValueError } from '../globals/index.js';
|
|
7
|
-
import { add, bool, compare, eq,
|
|
6
|
+
import { call, isDate, isEmpty, isIterable, isObject, isRegExp, notNull, ValueError } from '../globals/index.js';
|
|
7
|
+
import { add, bool, compare, eq, identity } from '../operators/index.js';
|
|
8
8
|
/**
|
|
9
9
|
* Make an iterator that returns accumulated sums, or accumulated results of other binary functions (specified via the optional `func` argument).
|
|
10
10
|
* @param iterable The iterable to accumulate
|
|
@@ -15,15 +15,18 @@ import { add, bool, compare, eq, id } from '../operators/index.js';
|
|
|
15
15
|
export function* accumulate(iterable, func = add, initial) {
|
|
16
16
|
const it = iter(iterable);
|
|
17
17
|
let total = initial;
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
if (initial == null) {
|
|
19
|
+
const head = it.next();
|
|
20
|
+
if (head.done)
|
|
21
|
+
return;
|
|
20
22
|
total = head.value;
|
|
21
|
-
|
|
23
|
+
}
|
|
24
|
+
while (true) {
|
|
22
25
|
yield total;
|
|
23
|
-
|
|
24
|
-
if (
|
|
26
|
+
const current = it.next();
|
|
27
|
+
if (current.done)
|
|
25
28
|
return;
|
|
26
|
-
total = func(total,
|
|
29
|
+
total = func(total, current.value);
|
|
27
30
|
}
|
|
28
31
|
}
|
|
29
32
|
/**
|
|
@@ -34,12 +37,12 @@ export function* accumulate(iterable, func = add, initial) {
|
|
|
34
37
|
* @example
|
|
35
38
|
```js
|
|
36
39
|
all([0])
|
|
37
|
-
//
|
|
40
|
+
// false
|
|
38
41
|
|
|
39
42
|
all([1, 2, 3])
|
|
40
43
|
// true
|
|
41
44
|
|
|
42
|
-
all([2, 4, 6]
|
|
45
|
+
all([2, 4, 6], n => n > 1)
|
|
43
46
|
// true
|
|
44
47
|
```
|
|
45
48
|
@see {@link any}
|
|
@@ -64,7 +67,7 @@ any([0])
|
|
|
64
67
|
any([0, 1, null, undefined])
|
|
65
68
|
// true
|
|
66
69
|
|
|
67
|
-
any([1, 4, 5]
|
|
70
|
+
any([1, 4, 5], n => n % 2 === 0)
|
|
68
71
|
// true
|
|
69
72
|
```
|
|
70
73
|
@see {@link all}
|
|
@@ -89,9 +92,6 @@ export function chain(...iterables) {
|
|
|
89
92
|
contains([1, 2, 3], 1)
|
|
90
93
|
// true
|
|
91
94
|
|
|
92
|
-
contains([1, 2, 3], 1, 2)
|
|
93
|
-
// false
|
|
94
|
-
|
|
95
95
|
contains({ 'a': 1, 'b': 2 }, 1)
|
|
96
96
|
// true
|
|
97
97
|
|
|
@@ -107,7 +107,8 @@ export function contains(collection, value) {
|
|
|
107
107
|
const includes = call(collection, 'includes', value);
|
|
108
108
|
if (includes != null)
|
|
109
109
|
return includes;
|
|
110
|
-
|
|
110
|
+
const items = isIterable(collection) ? collection : Object.values(collection);
|
|
111
|
+
return any(items, (x) => eq(value, x));
|
|
111
112
|
}
|
|
112
113
|
/**
|
|
113
114
|
* Returns a generator that drops elements from the iterable as long as the predicate is `true`; afterwards, returns every remaining element. Note, the generator does not produce any output until the predicate first becomes `false`.
|
|
@@ -119,9 +120,9 @@ export function* dropWhile(iterable, predicate) {
|
|
|
119
120
|
const it = iter(iterable);
|
|
120
121
|
while (true) {
|
|
121
122
|
const head = it.next();
|
|
123
|
+
if (head.done)
|
|
124
|
+
return head.value;
|
|
122
125
|
if (!predicate(head.value)) {
|
|
123
|
-
if (head.done)
|
|
124
|
-
return head.value;
|
|
125
126
|
yield head.value;
|
|
126
127
|
break;
|
|
127
128
|
}
|
|
@@ -140,14 +141,6 @@ export function iforEach(iterable, fun) {
|
|
|
140
141
|
}
|
|
141
142
|
}
|
|
142
143
|
}
|
|
143
|
-
export function IterableIterator(next) {
|
|
144
|
-
return {
|
|
145
|
-
next,
|
|
146
|
-
[Symbol.iterator]() {
|
|
147
|
-
return this;
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
144
|
/**
|
|
152
145
|
* Yields elements like `[index, item]` from an iterable. Index starts at zero by default.
|
|
153
146
|
* @template T
|
|
@@ -180,18 +173,20 @@ export function first(iterable) {
|
|
|
180
173
|
}
|
|
181
174
|
/**
|
|
182
175
|
* Creates a new generator that filters all falsy and empty values from iterable.
|
|
183
|
-
* @param
|
|
184
|
-
* @returns A
|
|
176
|
+
* @param iterable The iterable to compact
|
|
177
|
+
* @returns A generator with the filtered values.
|
|
185
178
|
* @example
|
|
186
179
|
```js
|
|
187
|
-
|
|
180
|
+
[...icompact([0, 1, false, 2, '', 3])]
|
|
188
181
|
// [1, 2, 3]
|
|
189
182
|
```
|
|
190
183
|
*/
|
|
191
184
|
export function* icompact(iterable) {
|
|
192
185
|
for (const value of iterable) {
|
|
193
|
-
|
|
186
|
+
// `isEmpty` reads arity and keys, which say nothing about these values
|
|
187
|
+
if (!isEmpty(value) || typeof value === 'function' || isDate(value) || isRegExp(value)) {
|
|
194
188
|
yield value;
|
|
189
|
+
}
|
|
195
190
|
}
|
|
196
191
|
}
|
|
197
192
|
/**
|
|
@@ -224,8 +219,12 @@ export function* iflatten(iterables) {
|
|
|
224
219
|
}
|
|
225
220
|
}
|
|
226
221
|
}
|
|
227
|
-
export function flatMap(iterable, mapFn =
|
|
228
|
-
|
|
222
|
+
export function flatMap(iterable, mapFn = identity) {
|
|
223
|
+
const toIterable = (x) => {
|
|
224
|
+
const mapped = mapFn(x);
|
|
225
|
+
return isIterable(mapped) ? mapped : [mapped];
|
|
226
|
+
};
|
|
227
|
+
return iflatten(imap(iterable, toIterable));
|
|
229
228
|
}
|
|
230
229
|
export function* islice(iterable, start, stop, step = 1) {
|
|
231
230
|
if (stop != null && stop < 0)
|
|
@@ -237,9 +236,9 @@ export function* islice(iterable, start, stop, step = 1) {
|
|
|
237
236
|
if (step < 0)
|
|
238
237
|
throw new ValueError(`step parameter can't be negative`);
|
|
239
238
|
for (const [i, value] of enumerate(iterable)) {
|
|
239
|
+
if (stop != null && i >= stop)
|
|
240
|
+
return;
|
|
240
241
|
if (i === start) {
|
|
241
|
-
if (stop && start + step > stop)
|
|
242
|
-
return value;
|
|
243
242
|
yield value;
|
|
244
243
|
start += step;
|
|
245
244
|
}
|
|
@@ -280,7 +279,7 @@ export function partition(iterable, predicate) {
|
|
|
280
279
|
/**
|
|
281
280
|
* Returns a generator for a sequence of numbers in the given range, starting from `start` (default 0) to `stop` (not-inclusive) in increments of `step` (default 1).
|
|
282
281
|
*
|
|
283
|
-
* `range(x)` is a shorthand for `range(0, x, 1)
|
|
282
|
+
* `range(x)` is a shorthand for `range(0, x, 1)`, or `range(0, x, -1)` when `x` is negative.
|
|
284
283
|
* @param args When called with a single argument, it is assigned to `stop` param. If two arguments are given, it will assign them to `(start, stop)`. When three arguments, it means `(start, stop, step)`.
|
|
285
284
|
* @example
|
|
286
285
|
```js
|
|
@@ -297,7 +296,7 @@ range(5, 0, -1)
|
|
|
297
296
|
// [5, 4, 3, 2, 1]
|
|
298
297
|
|
|
299
298
|
range(-3)
|
|
300
|
-
// []
|
|
299
|
+
// [0, -1, -2]
|
|
301
300
|
```
|
|
302
301
|
*/
|
|
303
302
|
export function* range(...args) {
|
|
@@ -338,7 +337,7 @@ reduce([1, 2, 3, 4, 5], (x, y) => x + y, 0)
|
|
|
338
337
|
export function reduce(iterable, reducer, initial) {
|
|
339
338
|
const it = iter(iterable);
|
|
340
339
|
let output = initial ?? it.next().value;
|
|
341
|
-
for (const [index, value] of enumerate(it)) {
|
|
340
|
+
for (const [index, value] of enumerate({ [Symbol.iterator]: () => it })) {
|
|
342
341
|
output = reducer(output, value, index);
|
|
343
342
|
}
|
|
344
343
|
return output;
|
|
@@ -357,17 +356,13 @@ export function sorted(args, key, reverse, compareFn) {
|
|
|
357
356
|
args = Object.keys(args);
|
|
358
357
|
}
|
|
359
358
|
if (typeof key === 'boolean') {
|
|
360
|
-
if (typeof reverse === 'function')
|
|
359
|
+
if (typeof reverse === 'function')
|
|
361
360
|
compareFn = reverse;
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
else {
|
|
365
|
-
reverse = true;
|
|
366
|
-
}
|
|
367
|
-
key = id;
|
|
361
|
+
reverse = key || reverse === true;
|
|
362
|
+
key = identity;
|
|
368
363
|
}
|
|
369
364
|
const copy = Array.from(args);
|
|
370
|
-
const _compare = compKey(compareFn || compare, key ||
|
|
365
|
+
const _compare = compKey(compareFn || compare, key || identity);
|
|
371
366
|
copy.sort(_compare);
|
|
372
367
|
if (reverse)
|
|
373
368
|
copy.reverse();
|
|
@@ -423,6 +418,8 @@ for item of zip([1, 2, 3], ['sugar', 'spice', 'nice'])
|
|
|
423
418
|
```
|
|
424
419
|
*/
|
|
425
420
|
export function* zip(...args) {
|
|
421
|
+
if (args.length === 0)
|
|
422
|
+
return;
|
|
426
423
|
const iterables = args.map(iter);
|
|
427
424
|
while (true) {
|
|
428
425
|
const items = [];
|
package/dist/math/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module math
|
|
5
5
|
*/
|
|
6
|
-
import { Predicate } from '../types.js';
|
|
6
|
+
import type { Predicate } from '../types.js';
|
|
7
7
|
/**
|
|
8
8
|
* Returns the absolute value of a number. The argument may be a number or an object implementing the `abs()`.
|
|
9
9
|
* @param x The value.
|
|
@@ -21,35 +21,18 @@ export declare function abs(x: any): number;
|
|
|
21
21
|
*/
|
|
22
22
|
export declare function round(x: number, digits?: number): number;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
* @param x A number.
|
|
26
|
-
* @returns Nearest integer less than or equal to number.
|
|
27
|
-
*
|
|
28
|
-
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor Math.floor()}
|
|
29
|
-
*/
|
|
30
|
-
export declare function floor(x: number): number;
|
|
31
|
-
/**
|
|
32
|
-
* Rounds up and returns the largest integer greater than or equal to a given number.
|
|
33
|
-
* @param x A number.
|
|
34
|
-
* @returns Nearest integer greater than or equal to number.
|
|
35
|
-
*
|
|
36
|
-
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil Math.ceil()}
|
|
37
|
-
*/
|
|
38
|
-
export declare function ceil(x: number): number;
|
|
39
|
-
/**
|
|
40
|
-
* Returns a tuple like `[x / y, x % y]`.
|
|
24
|
+
* Returns a tuple like `[q, r]` with the floored quotient of `x / y` and a remainder that takes the sign of `y`, so `q * y + r` gives `x`, as in Python.
|
|
41
25
|
*
|
|
42
26
|
* @param x
|
|
43
27
|
* @param y
|
|
44
28
|
* @returns
|
|
45
29
|
*/
|
|
46
30
|
export declare function divmod(x: number, y: number): [number, number];
|
|
47
|
-
export declare function
|
|
48
|
-
export declare function logBase(x: any, y: any): number;
|
|
31
|
+
export declare function logBase(x: number, y: number): number;
|
|
49
32
|
/**
|
|
50
33
|
* Returns the smallest element in an iterable. The optional `key` argument specifies a transform on the elements before comparing them. If the elements in the iterable are objects that implement a custom `lt` method, this will be called to compare.
|
|
51
34
|
* @param iterable The iterable to inspect.
|
|
52
|
-
* @param key Optional key function to transform the elements (default `
|
|
35
|
+
* @param key Optional key function to transform the elements (default `identity`).
|
|
53
36
|
* @returns The smallest element in the iterable.
|
|
54
37
|
*/
|
|
55
38
|
export declare function min(iterable: number[]): number;
|
|
@@ -57,7 +40,7 @@ export declare function min<T>(iterable: Iterable<T>, key?: Predicate<T>): T;
|
|
|
57
40
|
/**
|
|
58
41
|
* Returns the largest element in an iterable. The optional `key` argument specifies a transform on the elements before comparing them. If the elements in the iterable are objects that implement a custom `gt` method, this will be called to compare.
|
|
59
42
|
* @param iterable The iterable to inspect.
|
|
60
|
-
* @param key Optional key function to transform the elements (default `
|
|
43
|
+
* @param key Optional key function to transform the elements (default `identity`).
|
|
61
44
|
* @returns The largest element in the iterable.
|
|
62
45
|
*/
|
|
63
46
|
export declare function max(iterable: number[]): number;
|
|
@@ -72,24 +55,24 @@ export declare function max<T>(iterable: Iterable<T>, key?: Predicate<T>): T;
|
|
|
72
55
|
```js
|
|
73
56
|
let objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }]
|
|
74
57
|
|
|
75
|
-
mean(objects,
|
|
58
|
+
mean(objects, o => o.n)
|
|
76
59
|
// 5
|
|
77
60
|
```
|
|
78
61
|
*/
|
|
79
62
|
export declare function mean(iterable: number[]): number;
|
|
80
63
|
export declare function mean<T>(iterable: Iterable<T>, key?: Predicate<T>): number;
|
|
81
64
|
/**
|
|
82
|
-
* Sums
|
|
83
|
-
* @param args The elements to add
|
|
84
|
-
* @param
|
|
85
|
-
* @returns The total sum of
|
|
65
|
+
* Sums the items of an iterable and returns the total. The optional `key` argument specifies a transform on the elements before adding them.
|
|
66
|
+
* @param args The elements to add.
|
|
67
|
+
* @param key Optional key function to transform the elements (default `identity`).
|
|
68
|
+
* @returns The total sum of the iterable elements.
|
|
86
69
|
* @example
|
|
87
70
|
```js
|
|
88
71
|
sum([1, 2, 3, 4])
|
|
89
72
|
// 10
|
|
90
73
|
|
|
91
|
-
sum([1, 2
|
|
92
|
-
//
|
|
74
|
+
sum([{ n: 1 }, { n: 2 }], o => o.n)
|
|
75
|
+
// 3
|
|
93
76
|
```
|
|
94
77
|
*/
|
|
95
78
|
export declare function sum(args: number[]): number;
|
package/dist/math/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { call } from '../globals/index.js';
|
|
7
7
|
import { reduce } from '../itertools/index.js';
|
|
8
|
-
import { gt,
|
|
8
|
+
import { gt, identity, lt } from '../operators/index.js';
|
|
9
9
|
/**
|
|
10
10
|
* Returns the absolute value of a number. The argument may be a number or an object implementing the `abs()`.
|
|
11
11
|
* @param x The value.
|
|
@@ -28,43 +28,26 @@ export function abs(x) {
|
|
|
28
28
|
*/
|
|
29
29
|
export function round(x, digits = 0) {
|
|
30
30
|
const base = 10 ** digits;
|
|
31
|
-
|
|
31
|
+
const scaled = x * base;
|
|
32
|
+
// A number too large to scale has no digits left to round.
|
|
33
|
+
return Number.isFinite(scaled) ? Math.round(scaled) / base : Number(x);
|
|
32
34
|
}
|
|
33
35
|
/**
|
|
34
|
-
*
|
|
35
|
-
* @param x A number.
|
|
36
|
-
* @returns Nearest integer less than or equal to number.
|
|
37
|
-
*
|
|
38
|
-
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor Math.floor()}
|
|
39
|
-
*/
|
|
40
|
-
export function floor(x) {
|
|
41
|
-
return Math.floor(x);
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Rounds up and returns the largest integer greater than or equal to a given number.
|
|
45
|
-
* @param x A number.
|
|
46
|
-
* @returns Nearest integer greater than or equal to number.
|
|
47
|
-
*
|
|
48
|
-
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil Math.ceil()}
|
|
49
|
-
*/
|
|
50
|
-
export function ceil(x) {
|
|
51
|
-
return Math.ceil(x);
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Returns a tuple like `[x / y, x % y]`.
|
|
36
|
+
* Returns a tuple like `[q, r]` with the floored quotient of `x / y` and a remainder that takes the sign of `y`, so `q * y + r` gives `x`, as in Python.
|
|
55
37
|
*
|
|
56
38
|
* @param x
|
|
57
39
|
* @param y
|
|
58
40
|
* @returns
|
|
59
41
|
*/
|
|
60
42
|
export function divmod(x, y) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
43
|
+
let remainder = x % y;
|
|
44
|
+
let quotient = (x - remainder) / y;
|
|
45
|
+
if (remainder !== 0 && remainder < 0 !== y < 0) {
|
|
46
|
+
remainder += y;
|
|
47
|
+
quotient -= 1;
|
|
66
48
|
}
|
|
67
|
-
|
|
49
|
+
// A zero or NaN quotient keeps the sign of zero and the infinities of `x / y`.
|
|
50
|
+
return [Math.round(quotient) || Math.floor(x / y), remainder];
|
|
68
51
|
}
|
|
69
52
|
export function logBase(x, y) {
|
|
70
53
|
if (x > 0 && y > 0) {
|
|
@@ -72,13 +55,13 @@ export function logBase(x, y) {
|
|
|
72
55
|
}
|
|
73
56
|
return Number.NaN;
|
|
74
57
|
}
|
|
75
|
-
export function min(iterable, key =
|
|
58
|
+
export function min(iterable, key = identity) {
|
|
76
59
|
return reduce(iterable, (x, y) => (lt(key(x), key(y)) ? x : y));
|
|
77
60
|
}
|
|
78
|
-
export function max(iterable, key =
|
|
61
|
+
export function max(iterable, key = identity) {
|
|
79
62
|
return reduce(iterable, (x, y) => (gt(key(x), key(y)) ? x : y));
|
|
80
63
|
}
|
|
81
|
-
export function mean(iterable, key =
|
|
64
|
+
export function mean(iterable, key = identity) {
|
|
82
65
|
let total = 0;
|
|
83
66
|
let count = 0;
|
|
84
67
|
for (const value of iterable) {
|
|
@@ -89,7 +72,7 @@ export function mean(iterable, key = id) {
|
|
|
89
72
|
return total / count;
|
|
90
73
|
return Number.NaN;
|
|
91
74
|
}
|
|
92
|
-
export function sum(args, key =
|
|
75
|
+
export function sum(args, key = identity) {
|
|
93
76
|
let initial = 0;
|
|
94
77
|
for (const x of args) {
|
|
95
78
|
initial += key(x);
|
package/dist/mod.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './index.js';
|
package/dist/mod.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './index.js';
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module operators
|
|
5
5
|
*/
|
|
6
|
-
/** This is the identity function. It always returns the same value that was passed in */
|
|
7
|
-
export declare
|
|
6
|
+
/** This is the identity function. It always returns the same value that was passed in. */
|
|
7
|
+
export declare const identity: <T>(x: T) => T;
|
|
8
8
|
/**
|
|
9
9
|
* Called to implement truth value testing.
|
|
10
10
|
* @param x
|
|
@@ -27,7 +27,7 @@ export declare function isinstance(x: any, y: any): boolean;
|
|
|
27
27
|
*
|
|
28
28
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#parameters Array.sort()}
|
|
29
29
|
*/
|
|
30
|
-
export
|
|
30
|
+
export type Comparer<T = any> = (x: T, y: T) => number;
|
|
31
31
|
/**
|
|
32
32
|
* Checks whether `x` is a comparable type and returns the result of `x.compare(y)`.
|
|
33
33
|
* Otherwise the return value of the compare function is equivalent to `obj === other ? 0 : obj < other ? -1 : 1`
|
package/dist/operators/index.js
CHANGED
|
@@ -4,10 +4,8 @@
|
|
|
4
4
|
* @module operators
|
|
5
5
|
*/
|
|
6
6
|
import { call, isObject } from '../globals/index.js';
|
|
7
|
-
/** This is the identity function. It always returns the same value that was passed in */
|
|
8
|
-
export
|
|
9
|
-
return x;
|
|
10
|
-
}
|
|
7
|
+
/** This is the identity function. It always returns the same value that was passed in. */
|
|
8
|
+
export const identity = (x) => x;
|
|
11
9
|
/**
|
|
12
10
|
* Called to implement truth value testing.
|
|
13
11
|
* @param x
|
|
@@ -51,7 +49,9 @@ export function compare(x, y) {
|
|
|
51
49
|
const op = call(x, 'compare', y);
|
|
52
50
|
if (typeof op === 'number')
|
|
53
51
|
return op;
|
|
54
|
-
if (x
|
|
52
|
+
if (x instanceof Date && y instanceof Date)
|
|
53
|
+
return Math.sign(x.getTime() - y.getTime()) || 0;
|
|
54
|
+
if (lt(x, y))
|
|
55
55
|
return -1;
|
|
56
56
|
return 1;
|
|
57
57
|
}
|
|
@@ -63,7 +63,7 @@ export function compare(x, y) {
|
|
|
63
63
|
* @returns {boolean} `true` if `x` and `y` are equal or `false` otherwise.
|
|
64
64
|
*/
|
|
65
65
|
export function eq(x, y) {
|
|
66
|
-
return Object.is(x, y) || call(x, 'eq', y)
|
|
66
|
+
return x === y || Object.is(x, y) || !!call(x, 'eq', y);
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
69
|
* Compares two values to check if `x` is strictly less than `y`. If `x` is an object with a `lt` method, it returns `x.lt(y)`.
|
|
@@ -73,7 +73,8 @@ export function eq(x, y) {
|
|
|
73
73
|
* @returns {boolean} `true` if `x` is strictly less than `y` or `false` otherwise.
|
|
74
74
|
*/
|
|
75
75
|
export function lt(x, y) {
|
|
76
|
-
|
|
76
|
+
const op = call(x, 'lt', y);
|
|
77
|
+
return op != null ? !!op : x < y;
|
|
77
78
|
}
|
|
78
79
|
/**
|
|
79
80
|
* Compares two values to check if `x <= y`. If `x` is an object with a `lte` method, it returns `x.lte(y)`, also checks `x.eq(y)` and `x.lt(y)`.
|
|
@@ -85,13 +86,13 @@ export function lt(x, y) {
|
|
|
85
86
|
* @see {@link lt}
|
|
86
87
|
*/
|
|
87
88
|
export function lte(x, y) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (
|
|
93
|
-
return
|
|
94
|
-
return
|
|
89
|
+
const op = call(x, 'lte', y);
|
|
90
|
+
if (op != null)
|
|
91
|
+
return !!op;
|
|
92
|
+
const less = call(x, 'lt', y);
|
|
93
|
+
if (less != null)
|
|
94
|
+
return !!less || eq(x, y) || (call(y, 'lt', x) === false && x <= y);
|
|
95
|
+
return x <= y || eq(x, y);
|
|
95
96
|
}
|
|
96
97
|
/**
|
|
97
98
|
* Compares two values to check if `x` is strictly greater than `y`. If `x` is an object with a `gt` method, it returns `x.gt(y)`.
|
|
@@ -101,7 +102,8 @@ export function lte(x, y) {
|
|
|
101
102
|
* @returns {boolean} `true` if `x` is strictly greater than `y` or `false` otherwise.
|
|
102
103
|
*/
|
|
103
104
|
export function gt(x, y) {
|
|
104
|
-
|
|
105
|
+
const op = call(x, 'gt', y);
|
|
106
|
+
return op != null ? !!op : x > y;
|
|
105
107
|
}
|
|
106
108
|
/**
|
|
107
109
|
* Compares two values to check if `x >= y`. If `x` is an object with a `gte` method, it returns `x.gte(y)`, also checks `x.eq(y)` and `x.gt(y)`.
|
|
@@ -113,13 +115,13 @@ export function gt(x, y) {
|
|
|
113
115
|
* @see {@link gt}
|
|
114
116
|
*/
|
|
115
117
|
export function gte(x, y) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (
|
|
121
|
-
return
|
|
122
|
-
return
|
|
118
|
+
const op = call(x, 'gte', y);
|
|
119
|
+
if (op != null)
|
|
120
|
+
return !!op;
|
|
121
|
+
const greater = call(x, 'gt', y);
|
|
122
|
+
if (greater != null)
|
|
123
|
+
return !!greater || eq(x, y) || (call(y, 'gt', x) === false && x >= y);
|
|
124
|
+
return x >= y || eq(x, y);
|
|
123
125
|
}
|
|
124
126
|
/**
|
|
125
127
|
* The addition (+) operator. If `x` is an object with an `add` method, it returns `x.add(y)`.
|
|
@@ -199,6 +201,26 @@ export function pow(x, y) {
|
|
|
199
201
|
return op;
|
|
200
202
|
return x ** y;
|
|
201
203
|
}
|
|
204
|
+
/** Class names tell kinds apart across realms, where prototypes differ. */
|
|
205
|
+
function sameKind(x, y) {
|
|
206
|
+
if (!x || !y || typeof x !== 'object' || typeof y !== 'object')
|
|
207
|
+
return false;
|
|
208
|
+
const tag = Object.prototype.toString;
|
|
209
|
+
if (tag.call(x) !== tag.call(y))
|
|
210
|
+
return false;
|
|
211
|
+
return (x.constructor?.name ?? 'Object') === (y.constructor?.name ?? 'Object');
|
|
212
|
+
}
|
|
213
|
+
function isList(x) {
|
|
214
|
+
return Array.isArray(x) || (ArrayBuffer.isView(x) && !(x instanceof DataView));
|
|
215
|
+
}
|
|
216
|
+
function isDateOrRegExp(x) {
|
|
217
|
+
return x instanceof Date || x instanceof RegExp;
|
|
218
|
+
}
|
|
219
|
+
function sameDateOrRegExp(x, y) {
|
|
220
|
+
if (x instanceof Date)
|
|
221
|
+
return Object.is(x.getTime(), y.getTime());
|
|
222
|
+
return String(x) === String(y);
|
|
223
|
+
}
|
|
202
224
|
/**
|
|
203
225
|
* Performs a shallow comparison of two objects or arrays to check if they have the same keys, length and values.
|
|
204
226
|
* @param obj
|
|
@@ -209,8 +231,10 @@ export function pow(x, y) {
|
|
|
209
231
|
export function shallowEqual(obj, other) {
|
|
210
232
|
if (obj === other)
|
|
211
233
|
return true;
|
|
212
|
-
if (!obj
|
|
234
|
+
if (!sameKind(obj, other))
|
|
213
235
|
return false;
|
|
236
|
+
if (isDateOrRegExp(obj))
|
|
237
|
+
return sameDateOrRegExp(obj, other);
|
|
214
238
|
if (Array.isArray(obj)) {
|
|
215
239
|
// compare the arrays
|
|
216
240
|
if (obj.length !== other.length)
|
|
@@ -229,7 +253,7 @@ export function shallowEqual(obj, other) {
|
|
|
229
253
|
if (objKeys.length !== otherKeys.length)
|
|
230
254
|
return false;
|
|
231
255
|
for (const key of objKeys) {
|
|
232
|
-
if (!Object.
|
|
256
|
+
if (!Object.hasOwn(other, key) || obj[key] !== other[key]) {
|
|
233
257
|
return false;
|
|
234
258
|
}
|
|
235
259
|
}
|
|
@@ -237,21 +261,26 @@ export function shallowEqual(obj, other) {
|
|
|
237
261
|
}
|
|
238
262
|
return false;
|
|
239
263
|
}
|
|
240
|
-
export function deepEqual(obj, other, checker = eq, seen = new
|
|
264
|
+
export function deepEqual(obj, other, checker = eq, seen = new WeakMap()) {
|
|
265
|
+
if (!(seen instanceof WeakMap))
|
|
266
|
+
seen = new WeakMap();
|
|
241
267
|
if (checker(obj, other))
|
|
242
268
|
return true;
|
|
243
|
-
if (!obj
|
|
244
|
-
return false;
|
|
245
|
-
if (obj.prototype !== other.prototype)
|
|
246
|
-
return false;
|
|
247
|
-
if (seen.has(obj) && seen.has(other))
|
|
269
|
+
if (!sameKind(obj, other))
|
|
248
270
|
return false;
|
|
249
|
-
if (
|
|
271
|
+
if (isDateOrRegExp(obj))
|
|
272
|
+
return sameDateOrRegExp(obj, other);
|
|
273
|
+
// A pair that was compared before needs no second walk: it either held, or the call has returned.
|
|
274
|
+
const partners = seen.get(obj) ?? new WeakSet();
|
|
275
|
+
if (partners.has(other))
|
|
276
|
+
return true;
|
|
277
|
+
seen.set(obj, partners.add(other));
|
|
278
|
+
if (isList(obj)) {
|
|
250
279
|
// compare the arrays
|
|
251
280
|
if (obj.length !== other.length)
|
|
252
281
|
return false;
|
|
253
282
|
for (let i = 0; i < obj.length; i++) {
|
|
254
|
-
if (!deepEqual(obj[i], other[i], checker)) {
|
|
283
|
+
if (!deepEqual(obj[i], other[i], checker, seen)) {
|
|
255
284
|
return false;
|
|
256
285
|
}
|
|
257
286
|
}
|
|
@@ -270,8 +299,6 @@ export function deepEqual(obj, other, checker = eq, seen = new WeakSet()) {
|
|
|
270
299
|
// compare keys and values
|
|
271
300
|
if (obj.size !== other.size)
|
|
272
301
|
return false;
|
|
273
|
-
seen.add(obj);
|
|
274
|
-
seen.add(other);
|
|
275
302
|
for (const key of obj.keys()) {
|
|
276
303
|
if (!other.has(key))
|
|
277
304
|
return false;
|
|
@@ -287,11 +314,8 @@ export function deepEqual(obj, other, checker = eq, seen = new WeakSet()) {
|
|
|
287
314
|
const otherKeys = Object.keys(other);
|
|
288
315
|
if (objKeys.length !== otherKeys.length)
|
|
289
316
|
return false;
|
|
290
|
-
seen.add(obj);
|
|
291
|
-
seen.add(other);
|
|
292
317
|
for (const key of objKeys) {
|
|
293
|
-
if (!Object.
|
|
294
|
-
!deepEqual(obj[key], other[key], checker, seen)) {
|
|
318
|
+
if (!Object.hasOwn(other, key) || !deepEqual(obj[key], other[key], checker, seen)) {
|
|
295
319
|
return false;
|
|
296
320
|
}
|
|
297
321
|
}
|
package/dist/random/index.js
CHANGED
|
@@ -11,7 +11,8 @@ import { isObject } from '../globals/index.js';
|
|
|
11
11
|
* @returns {number}
|
|
12
12
|
*/
|
|
13
13
|
export function random(min = 0, max = 1) {
|
|
14
|
-
|
|
14
|
+
const value = Math.random() * (max - min) + min;
|
|
15
|
+
return value === max ? min : value;
|
|
15
16
|
}
|
|
16
17
|
/**
|
|
17
18
|
* Returns a random integer between a [min, max] value (inclusive).
|
|
@@ -20,7 +21,9 @@ export function random(min = 0, max = 1) {
|
|
|
20
21
|
* @returns {number}
|
|
21
22
|
*/
|
|
22
23
|
export function randomInt(min = 0, max = 1) {
|
|
23
|
-
|
|
24
|
+
const low = Math.ceil(Math.min(min, max));
|
|
25
|
+
const high = Math.floor(Math.max(min, max));
|
|
26
|
+
return low + Math.floor(random(0, high - low + 1));
|
|
24
27
|
}
|
|
25
28
|
/**
|
|
26
29
|
* Returns the item at some random index in a sequence.
|
|
@@ -42,7 +45,7 @@ export function choice(arr) {
|
|
|
42
45
|
export function sample(arr, size) {
|
|
43
46
|
if (!arr?.length || arr.length < size)
|
|
44
47
|
return [];
|
|
45
|
-
return shuffle(arr.slice()).slice(
|
|
48
|
+
return shuffle(arr.slice()).slice(0, size);
|
|
46
49
|
}
|
|
47
50
|
/**
|
|
48
51
|
* Shuffles a collection elements in-place. Uses the Fisher-Yates algorithm for uniform shuffling. If collection is an Object it returns shuffled `Object.values()`.
|
|
@@ -53,11 +56,11 @@ export function sample(arr, size) {
|
|
|
53
56
|
* @template T
|
|
54
57
|
*/
|
|
55
58
|
export function shuffle(arr, size) {
|
|
56
|
-
if (!arr?.length)
|
|
57
|
-
return arr;
|
|
58
59
|
if (isObject(arr))
|
|
59
60
|
arr = Object.values(arr);
|
|
60
|
-
if (
|
|
61
|
+
if (!arr?.length)
|
|
62
|
+
return arr;
|
|
63
|
+
if (size == null || size >= arr.length)
|
|
61
64
|
size = arr.length - 1;
|
|
62
65
|
for (let i = 0; i <= size; i++) {
|
|
63
66
|
const j = randomInt(i, size);
|
package/dist/string/index.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export declare function capitalize(s: string): string;
|
|
|
33
33
|
/**
|
|
34
34
|
* Split a string into an array of its words.
|
|
35
35
|
* @param {string} s The string to split
|
|
36
|
-
* @param {RegExp | string} [pattern] The
|
|
36
|
+
* @param {RegExp | string} [pattern] The separator to split on, instead of matching words
|
|
37
37
|
* @returns {string[]} Returns the words array.
|
|
38
38
|
* @example
|
|
39
39
|
```js
|