atomic-fns 1.1.7 → 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.js +1 -1
- package/dist/collections/LRUCache.d.ts +6 -3
- package/dist/collections/LRUCache.js +24 -11
- package/dist/collections/SortedMap.js +2 -2
- package/dist/collections/SortedTree.d.ts +2 -2
- package/dist/collections/SortedTree.js +3 -2
- package/dist/collections/SplayTree.d.ts +7 -5
- package/dist/collections/SplayTree.js +39 -26
- package/dist/collections/Trie.d.ts +1 -1
- package/dist/collections/Trie.js +26 -26
- package/dist/collections/deque.d.ts +1 -1
- package/dist/collections/deque.js +17 -10
- package/dist/collections/frozenset.js +4 -1
- package/dist/collections/index.d.ts +13 -32
- package/dist/collections/index.js +210 -82
- package/dist/decimal/index.d.ts +5 -2
- package/dist/decimal/index.js +63 -27
- package/dist/functools/index.d.ts +6 -30
- package/dist/functools/index.js +24 -56
- package/dist/globals/index.d.ts +3 -20
- package/dist/globals/index.js +23 -39
- package/dist/i18n/currency.d.ts +3 -0
- package/dist/i18n/currency.js +22 -7
- package/dist/i18n/date/index.d.ts +17 -10
- package/dist/i18n/date/index.js +79 -58
- package/dist/i18n/date/utils.d.ts +4 -5
- package/dist/i18n/date/utils.js +15 -113
- package/dist/i18n/duration.d.ts +11 -10
- package/dist/i18n/duration.js +38 -32
- package/dist/i18n/format.d.ts +5 -2
- package/dist/i18n/format.js +81 -209
- package/dist/i18n/index.d.ts +2 -1
- package/dist/itertools/index.d.ts +9 -13
- package/dist/itertools/index.js +38 -41
- package/dist/math/index.d.ts +10 -27
- package/dist/math/index.js +16 -33
- package/dist/operators/index.d.ts +1 -5
- package/dist/operators/index.js +60 -40
- 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/i18n/index.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module itertools
|
|
5
5
|
*/
|
|
6
|
-
import { add, Comparer } from '../operators/index.js';
|
|
7
|
-
import { Function, Iteratee, Predicate } from '../types';
|
|
6
|
+
import { add, type Comparer } from '../operators/index.js';
|
|
7
|
+
import type { Function, Iteratee, Predicate } from '../types.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
|
|
@@ -21,7 +21,7 @@ export declare function accumulate<T>(iterable: Iterable<T>, func?: typeof add,
|
|
|
21
21
|
* @example
|
|
22
22
|
```js
|
|
23
23
|
all([0])
|
|
24
|
-
//
|
|
24
|
+
// false
|
|
25
25
|
|
|
26
26
|
all([1, 2, 3])
|
|
27
27
|
// true
|
|
@@ -62,9 +62,6 @@ export declare function chain<T>(...iterables: Array<Iterable<T>>): Generator<T,
|
|
|
62
62
|
contains([1, 2, 3], 1)
|
|
63
63
|
// true
|
|
64
64
|
|
|
65
|
-
contains([1, 2, 3], 1, 2)
|
|
66
|
-
// false
|
|
67
|
-
|
|
68
65
|
contains({ 'a': 1, 'b': 2 }, 1)
|
|
69
66
|
// true
|
|
70
67
|
|
|
@@ -83,7 +80,6 @@ export declare function contains(collection: Iterable<any>, value: any): boolean
|
|
|
83
80
|
*/
|
|
84
81
|
export declare function dropWhile<T>(iterable: Iterable<T>, predicate: Predicate<T>): Generator<T, T, unknown>;
|
|
85
82
|
export declare function iforEach<T>(iterable: Iterable<T>, fun: Iteratee<T>): void;
|
|
86
|
-
export declare function IterableIterator<T = any>(next: Iterator<T>['next']): Iterable<T> & Iterator<T>;
|
|
87
83
|
/**
|
|
88
84
|
* Yields elements like `[index, item]` from an iterable. Index starts at zero by default.
|
|
89
85
|
* @template T
|
|
@@ -109,11 +105,11 @@ export declare function enumerate<T>(iterable: Iterable<T>, start?: number): Gen
|
|
|
109
105
|
export declare function first<T>(iterable: Iterable<T>): T;
|
|
110
106
|
/**
|
|
111
107
|
* Creates a new generator that filters all falsy and empty values from iterable.
|
|
112
|
-
* @param
|
|
113
|
-
* @returns A
|
|
108
|
+
* @param iterable The iterable to compact
|
|
109
|
+
* @returns A generator with the filtered values.
|
|
114
110
|
* @example
|
|
115
111
|
```js
|
|
116
|
-
|
|
112
|
+
[...icompact([0, 1, false, 2, '', 3])]
|
|
117
113
|
// [1, 2, 3]
|
|
118
114
|
```
|
|
119
115
|
*/
|
|
@@ -134,7 +130,7 @@ export declare function imap<T, TReturn = any>(iterable: Iterable<T>, mapFn: Pre
|
|
|
134
130
|
*/
|
|
135
131
|
export declare function iflatten<T = any>(iterables: Iterable<Iterable<T>>): Generator<T, void, unknown>;
|
|
136
132
|
export declare function flatMap<T>(iterable: Iterable<T>, mapFn?: (x: T) => any): Generator<T, void, unknown>;
|
|
137
|
-
export declare function islice<T>(iterable: Iterable<T>, start: number, stop?: number, step?: number): Generator<T,
|
|
133
|
+
export declare function islice<T>(iterable: Iterable<T>, start: number, stop?: number, step?: number): Generator<T, void, unknown>;
|
|
138
134
|
export declare function itake<T>(n: number, iterable: Iterable<T>): Generator<T, void, unknown>;
|
|
139
135
|
/**
|
|
140
136
|
* Returns an Iterator from the elements of a collection or the object keys.
|
|
@@ -146,7 +142,7 @@ export declare function partition<T>(iterable: Iterable<T>, predicate: Predicate
|
|
|
146
142
|
/**
|
|
147
143
|
* 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).
|
|
148
144
|
*
|
|
149
|
-
* `range(x)` is a shorthand for `range(0, x, 1)
|
|
145
|
+
* `range(x)` is a shorthand for `range(0, x, 1)`, or `range(0, x, -1)` when `x` is negative.
|
|
150
146
|
* @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)`.
|
|
151
147
|
* @example
|
|
152
148
|
```js
|
|
@@ -163,7 +159,7 @@ range(5, 0, -1)
|
|
|
163
159
|
// [5, 4, 3, 2, 1]
|
|
164
160
|
|
|
165
161
|
range(-3)
|
|
166
|
-
// []
|
|
162
|
+
// [0, -1, -2]
|
|
167
163
|
```
|
|
168
164
|
*/
|
|
169
165
|
export declare function range(...args: number[]): Generator<number, void, unknown>;
|
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,12 +15,15 @@ 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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
if (initial == null) {
|
|
19
|
+
const head = it.next();
|
|
20
|
+
if (head.done)
|
|
21
|
+
return;
|
|
22
|
+
total = head.value;
|
|
23
|
+
}
|
|
24
|
+
while (true) {
|
|
22
25
|
yield total;
|
|
23
|
-
current = it.next();
|
|
26
|
+
const current = it.next();
|
|
24
27
|
if (current.done)
|
|
25
28
|
return;
|
|
26
29
|
total = func(total, current.value);
|
|
@@ -34,7 +37,7 @@ 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
|
|
@@ -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 log2(x: number): number;
|
|
48
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;
|
|
@@ -79,17 +62,17 @@ mean(objects, o => o.n)
|
|
|
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);
|
|
@@ -3,10 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module operators
|
|
5
5
|
*/
|
|
6
|
-
/** @deprecated Use the `identity` function instead.
|
|
7
|
-
* @see {@link identity}
|
|
8
|
-
*/
|
|
9
|
-
export declare function id(x: any): any;
|
|
10
6
|
/** This is the identity function. It always returns the same value that was passed in. */
|
|
11
7
|
export declare const identity: <T>(x: T) => T;
|
|
12
8
|
/**
|
|
@@ -31,7 +27,7 @@ export declare function isinstance(x: any, y: any): boolean;
|
|
|
31
27
|
*
|
|
32
28
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#parameters Array.sort()}
|
|
33
29
|
*/
|
|
34
|
-
export
|
|
30
|
+
export type Comparer<T = any> = (x: T, y: T) => number;
|
|
35
31
|
/**
|
|
36
32
|
* Checks whether `x` is a comparable type and returns the result of `x.compare(y)`.
|
|
37
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,12 +4,6 @@
|
|
|
4
4
|
* @module operators
|
|
5
5
|
*/
|
|
6
6
|
import { call, isObject } from '../globals/index.js';
|
|
7
|
-
/** @deprecated Use the `identity` function instead.
|
|
8
|
-
* @see {@link identity}
|
|
9
|
-
*/
|
|
10
|
-
export function id(x) {
|
|
11
|
-
return x;
|
|
12
|
-
}
|
|
13
7
|
/** This is the identity function. It always returns the same value that was passed in. */
|
|
14
8
|
export const identity = (x) => x;
|
|
15
9
|
/**
|
|
@@ -55,7 +49,9 @@ export function compare(x, y) {
|
|
|
55
49
|
const op = call(x, 'compare', y);
|
|
56
50
|
if (typeof op === 'number')
|
|
57
51
|
return op;
|
|
58
|
-
if (x
|
|
52
|
+
if (x instanceof Date && y instanceof Date)
|
|
53
|
+
return Math.sign(x.getTime() - y.getTime()) || 0;
|
|
54
|
+
if (lt(x, y))
|
|
59
55
|
return -1;
|
|
60
56
|
return 1;
|
|
61
57
|
}
|
|
@@ -67,7 +63,7 @@ export function compare(x, y) {
|
|
|
67
63
|
* @returns {boolean} `true` if `x` and `y` are equal or `false` otherwise.
|
|
68
64
|
*/
|
|
69
65
|
export function eq(x, y) {
|
|
70
|
-
return Object.is(x, y) || call(x, 'eq', y)
|
|
66
|
+
return x === y || Object.is(x, y) || !!call(x, 'eq', y);
|
|
71
67
|
}
|
|
72
68
|
/**
|
|
73
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)`.
|
|
@@ -77,7 +73,8 @@ export function eq(x, y) {
|
|
|
77
73
|
* @returns {boolean} `true` if `x` is strictly less than `y` or `false` otherwise.
|
|
78
74
|
*/
|
|
79
75
|
export function lt(x, y) {
|
|
80
|
-
|
|
76
|
+
const op = call(x, 'lt', y);
|
|
77
|
+
return op != null ? !!op : x < y;
|
|
81
78
|
}
|
|
82
79
|
/**
|
|
83
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)`.
|
|
@@ -89,13 +86,13 @@ export function lt(x, y) {
|
|
|
89
86
|
* @see {@link lt}
|
|
90
87
|
*/
|
|
91
88
|
export function lte(x, y) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (
|
|
97
|
-
return
|
|
98
|
-
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);
|
|
99
96
|
}
|
|
100
97
|
/**
|
|
101
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)`.
|
|
@@ -105,7 +102,8 @@ export function lte(x, y) {
|
|
|
105
102
|
* @returns {boolean} `true` if `x` is strictly greater than `y` or `false` otherwise.
|
|
106
103
|
*/
|
|
107
104
|
export function gt(x, y) {
|
|
108
|
-
|
|
105
|
+
const op = call(x, 'gt', y);
|
|
106
|
+
return op != null ? !!op : x > y;
|
|
109
107
|
}
|
|
110
108
|
/**
|
|
111
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)`.
|
|
@@ -117,13 +115,13 @@ export function gt(x, y) {
|
|
|
117
115
|
* @see {@link gt}
|
|
118
116
|
*/
|
|
119
117
|
export function gte(x, y) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (
|
|
125
|
-
return
|
|
126
|
-
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);
|
|
127
125
|
}
|
|
128
126
|
/**
|
|
129
127
|
* The addition (+) operator. If `x` is an object with an `add` method, it returns `x.add(y)`.
|
|
@@ -203,6 +201,26 @@ export function pow(x, y) {
|
|
|
203
201
|
return op;
|
|
204
202
|
return x ** y;
|
|
205
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
|
+
}
|
|
206
224
|
/**
|
|
207
225
|
* Performs a shallow comparison of two objects or arrays to check if they have the same keys, length and values.
|
|
208
226
|
* @param obj
|
|
@@ -213,8 +231,10 @@ export function pow(x, y) {
|
|
|
213
231
|
export function shallowEqual(obj, other) {
|
|
214
232
|
if (obj === other)
|
|
215
233
|
return true;
|
|
216
|
-
if (!obj
|
|
234
|
+
if (!sameKind(obj, other))
|
|
217
235
|
return false;
|
|
236
|
+
if (isDateOrRegExp(obj))
|
|
237
|
+
return sameDateOrRegExp(obj, other);
|
|
218
238
|
if (Array.isArray(obj)) {
|
|
219
239
|
// compare the arrays
|
|
220
240
|
if (obj.length !== other.length)
|
|
@@ -233,7 +253,7 @@ export function shallowEqual(obj, other) {
|
|
|
233
253
|
if (objKeys.length !== otherKeys.length)
|
|
234
254
|
return false;
|
|
235
255
|
for (const key of objKeys) {
|
|
236
|
-
if (!Object.
|
|
256
|
+
if (!Object.hasOwn(other, key) || obj[key] !== other[key]) {
|
|
237
257
|
return false;
|
|
238
258
|
}
|
|
239
259
|
}
|
|
@@ -241,21 +261,26 @@ export function shallowEqual(obj, other) {
|
|
|
241
261
|
}
|
|
242
262
|
return false;
|
|
243
263
|
}
|
|
244
|
-
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();
|
|
245
267
|
if (checker(obj, other))
|
|
246
268
|
return true;
|
|
247
|
-
if (!obj
|
|
248
|
-
return false;
|
|
249
|
-
if (obj.prototype !== other.prototype)
|
|
269
|
+
if (!sameKind(obj, other))
|
|
250
270
|
return false;
|
|
251
|
-
if (
|
|
252
|
-
return
|
|
253
|
-
|
|
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)) {
|
|
254
279
|
// compare the arrays
|
|
255
280
|
if (obj.length !== other.length)
|
|
256
281
|
return false;
|
|
257
282
|
for (let i = 0; i < obj.length; i++) {
|
|
258
|
-
if (!deepEqual(obj[i], other[i], checker)) {
|
|
283
|
+
if (!deepEqual(obj[i], other[i], checker, seen)) {
|
|
259
284
|
return false;
|
|
260
285
|
}
|
|
261
286
|
}
|
|
@@ -274,8 +299,6 @@ export function deepEqual(obj, other, checker = eq, seen = new WeakSet()) {
|
|
|
274
299
|
// compare keys and values
|
|
275
300
|
if (obj.size !== other.size)
|
|
276
301
|
return false;
|
|
277
|
-
seen.add(obj);
|
|
278
|
-
seen.add(other);
|
|
279
302
|
for (const key of obj.keys()) {
|
|
280
303
|
if (!other.has(key))
|
|
281
304
|
return false;
|
|
@@ -291,11 +314,8 @@ export function deepEqual(obj, other, checker = eq, seen = new WeakSet()) {
|
|
|
291
314
|
const otherKeys = Object.keys(other);
|
|
292
315
|
if (objKeys.length !== otherKeys.length)
|
|
293
316
|
return false;
|
|
294
|
-
seen.add(obj);
|
|
295
|
-
seen.add(other);
|
|
296
317
|
for (const key of objKeys) {
|
|
297
|
-
if (!Object.
|
|
298
|
-
!deepEqual(obj[key], other[key], checker, seen)) {
|
|
318
|
+
if (!Object.hasOwn(other, key) || !deepEqual(obj[key], other[key], checker, seen)) {
|
|
299
319
|
return false;
|
|
300
320
|
}
|
|
301
321
|
}
|