atomic-fns 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +397 -91
- package/dist/array/index.d.ts +9 -0
- package/dist/array/index.js +9 -0
- package/dist/array/list.d.ts +99 -0
- package/dist/array/list.js +133 -0
- package/dist/array/sets.d.ts +130 -0
- package/dist/array/sets.js +213 -0
- package/dist/async/index.d.ts +6 -0
- package/dist/async/index.js +6 -0
- package/dist/async/retry.d.ts +38 -0
- package/dist/async/retry.js +56 -0
- package/dist/async/sleep.d.ts +42 -0
- package/dist/async/sleep.js +76 -0
- package/dist/collections/bisect.d.ts +103 -0
- package/dist/collections/bisect.js +157 -0
- package/dist/collections/deque.d.ts +67 -97
- package/dist/collections/deque.js +197 -256
- package/dist/collections/entries.d.ts +89 -0
- package/dist/collections/entries.js +131 -0
- package/dist/collections/frozen-set.d.ts +42 -0
- package/dist/collections/frozen-set.js +64 -0
- package/dist/collections/group.d.ts +141 -0
- package/dist/collections/group.js +241 -0
- package/dist/collections/heap.d.ts +64 -0
- package/dist/collections/heap.js +205 -0
- package/dist/collections/index.d.ts +15 -623
- package/dist/collections/index.js +14 -844
- package/dist/collections/internal/arrayKeys.d.ts +19 -0
- package/dist/collections/internal/arrayKeys.js +83 -0
- package/dist/collections/internal/invariants.d.ts +4 -0
- package/dist/collections/internal/invariants.js +12 -0
- package/dist/collections/internal/iterable.d.ts +25 -0
- package/dist/collections/internal/iterable.js +62 -0
- package/dist/collections/iterate.d.ts +162 -0
- package/dist/collections/iterate.js +188 -0
- package/dist/collections/lru-cache.d.ts +58 -0
- package/dist/collections/lru-cache.js +164 -0
- package/dist/collections/order.d.ts +19 -0
- package/dist/collections/order.js +38 -0
- package/dist/collections/shape.d.ts +32 -0
- package/dist/collections/shape.js +86 -0
- package/dist/collections/sorted-map.d.ts +171 -0
- package/dist/collections/sorted-map.js +845 -0
- package/dist/collections/sorted-set.d.ts +103 -0
- package/dist/collections/sorted-set.js +147 -0
- package/dist/collections/splay-tree.d.ts +82 -0
- package/dist/collections/splay-tree.js +354 -0
- package/dist/collections/trie.d.ts +58 -0
- package/dist/collections/trie.js +196 -0
- package/dist/decimal/currency.d.ts +211 -0
- package/dist/decimal/currency.js +321 -0
- package/dist/decimal/decimal.d.ts +299 -0
- package/dist/decimal/decimal.js +660 -0
- package/dist/decimal/index.d.ts +11 -148
- package/dist/decimal/index.js +10 -410
- package/dist/decimal/internal/bits.d.ts +2 -0
- package/dist/decimal/internal/bits.js +7 -0
- package/dist/decimal/internal/echo.d.ts +4 -0
- package/dist/decimal/internal/echo.js +6 -0
- package/dist/decimal/internal/isqrt.d.ts +9 -0
- package/dist/decimal/internal/isqrt.js +34 -0
- package/dist/decimal/internal/locale.d.ts +7 -0
- package/dist/decimal/internal/locale.js +24 -0
- package/dist/decimal/internal/minor-units.d.ts +2 -0
- package/dist/decimal/internal/minor-units.js +33 -0
- package/dist/decimal/internal/pow10.d.ts +24 -0
- package/dist/decimal/internal/pow10.js +96 -0
- package/dist/encoding/base64.d.ts +39 -0
- package/dist/encoding/base64.js +53 -0
- package/dist/encoding/hex.d.ts +23 -0
- package/dist/encoding/hex.js +34 -0
- package/dist/encoding/index.d.ts +6 -0
- package/dist/encoding/index.js +6 -0
- package/dist/function/debounce.d.ts +68 -0
- package/dist/function/debounce.js +203 -0
- package/dist/function/index.d.ts +6 -0
- package/dist/function/index.js +6 -0
- package/dist/function/shared.d.ts +2 -0
- package/dist/function/shared.js +5 -0
- package/dist/function/wrap.d.ts +130 -0
- package/dist/function/wrap.js +113 -0
- package/dist/hash/digest.d.ts +18 -0
- package/dist/hash/digest.js +26 -0
- package/dist/hash/hash.d.ts +22 -0
- package/dist/hash/hash.js +252 -0
- package/dist/hash/hashString.d.ts +13 -0
- package/dist/hash/hashString.js +53 -0
- package/dist/hash/index.d.ts +8 -0
- package/dist/hash/index.js +8 -0
- package/dist/hash/stableStringify.d.ts +19 -0
- package/dist/hash/stableStringify.js +102 -0
- package/dist/id/index.d.ts +7 -0
- package/dist/id/index.js +7 -0
- package/dist/id/nanoid.d.ts +16 -0
- package/dist/id/nanoid.js +65 -0
- package/dist/id/uniqueId.d.ts +14 -0
- package/dist/id/uniqueId.js +20 -0
- package/dist/id/uuid.d.ts +25 -0
- package/dist/id/uuid.js +64 -0
- package/dist/index.d.ts +15 -8
- package/dist/index.js +15 -8
- package/dist/internal/bytes.d.ts +11 -0
- package/dist/internal/bytes.js +33 -0
- package/dist/internal/codec.d.ts +11 -0
- package/dist/internal/codec.js +84 -0
- package/dist/internal/compare.d.ts +10 -0
- package/dist/internal/compare.js +26 -0
- package/dist/internal/crypto.d.ts +5 -0
- package/dist/internal/crypto.js +11 -0
- package/dist/internal/keys.d.ts +12 -0
- package/dist/internal/keys.js +23 -0
- package/dist/internal/kind.d.ts +44 -0
- package/dist/internal/kind.js +139 -0
- package/dist/internal/sparse.d.ts +51 -0
- package/dist/internal/sparse.js +104 -0
- package/dist/internal/text.d.ts +7 -0
- package/dist/internal/text.js +15 -0
- package/dist/internal/timer.d.ts +10 -0
- package/dist/internal/timer.js +17 -0
- package/dist/internal/truncate.d.ts +10 -0
- package/dist/internal/truncate.js +22 -0
- package/dist/internal/walk.d.ts +47 -0
- package/dist/internal/walk.js +100 -0
- package/dist/is/index.d.ts +8 -0
- package/dist/is/index.js +8 -0
- package/dist/is/isArrayLike.d.ts +18 -0
- package/dist/is/isArrayLike.js +25 -0
- package/dist/is/isError.d.ts +13 -0
- package/dist/is/isError.js +18 -0
- package/dist/is/isNil.d.ts +12 -0
- package/dist/is/isNil.js +14 -0
- package/dist/is/isPlainObject.d.ts +15 -0
- package/dist/is/isPlainObject.js +34 -0
- package/dist/number/index.d.ts +7 -0
- package/dist/number/index.js +7 -0
- package/dist/number/round.d.ts +86 -0
- package/dist/number/round.js +130 -0
- package/dist/number/stats.d.ts +52 -0
- package/dist/number/stats.js +115 -0
- package/dist/object/cloneDeep.d.ts +28 -0
- package/dist/object/cloneDeep.js +200 -0
- package/dist/object/index.d.ts +14 -0
- package/dist/object/index.js +13 -0
- package/dist/object/isEqual.d.ts +64 -0
- package/dist/object/isEqual.js +289 -0
- package/dist/object/matches.d.ts +40 -0
- package/dist/object/matches.js +284 -0
- package/dist/object/merge.d.ts +66 -0
- package/dist/object/merge.js +272 -0
- package/dist/object/parsePath.d.ts +22 -0
- package/dist/object/parsePath.js +111 -0
- package/dist/object/path.d.ts +85 -0
- package/dist/object/path.js +208 -0
- package/dist/object/pick.d.ts +91 -0
- package/dist/object/pick.js +180 -0
- package/dist/object/reshape.d.ts +73 -0
- package/dist/object/reshape.js +144 -0
- package/dist/random/index.d.ts +96 -32
- package/dist/random/index.js +215 -53
- package/dist/string/case.d.ts +71 -0
- package/dist/string/case.js +152 -0
- package/dist/string/fold.d.ts +35 -0
- package/dist/string/fold.js +100 -0
- package/dist/string/index.d.ts +6 -187
- package/dist/string/index.js +6 -224
- package/dist/string/truncate.d.ts +25 -0
- package/dist/string/truncate.js +44 -0
- package/dist/string/words.d.ts +27 -0
- package/dist/string/words.js +241 -0
- package/package.json +99 -51
- package/dist/collections/BTree.d.ts +0 -230
- package/dist/collections/BTree.js +0 -1143
- package/dist/collections/Heap.d.ts +0 -69
- package/dist/collections/Heap.js +0 -181
- package/dist/collections/LRUCache.d.ts +0 -83
- package/dist/collections/LRUCache.js +0 -139
- package/dist/collections/SortedMap.d.ts +0 -92
- package/dist/collections/SortedMap.js +0 -131
- package/dist/collections/SortedSet.d.ts +0 -69
- package/dist/collections/SortedSet.js +0 -99
- package/dist/collections/SortedTree.d.ts +0 -103
- package/dist/collections/SortedTree.js +0 -142
- package/dist/collections/SplayTree.d.ts +0 -107
- package/dist/collections/SplayTree.js +0 -351
- package/dist/collections/Trie.d.ts +0 -42
- package/dist/collections/Trie.js +0 -104
- package/dist/collections/abc.d.ts +0 -152
- package/dist/collections/abc.js +0 -39
- package/dist/collections/frozenset.d.ts +0 -19
- package/dist/collections/frozenset.js +0 -33
- package/dist/functools/index.d.ts +0 -106
- package/dist/functools/index.js +0 -203
- package/dist/globals/index.d.ts +0 -268
- package/dist/globals/index.js +0 -447
- package/dist/i18n/currency.d.ts +0 -27
- package/dist/i18n/currency.js +0 -100
- package/dist/i18n/date/index.d.ts +0 -210
- package/dist/i18n/date/index.js +0 -552
- package/dist/i18n/date/utils.d.ts +0 -64
- package/dist/i18n/date/utils.js +0 -192
- package/dist/i18n/duration.d.ts +0 -113
- package/dist/i18n/duration.js +0 -398
- package/dist/i18n/format.d.ts +0 -34
- package/dist/i18n/format.js +0 -378
- package/dist/i18n/index.d.ts +0 -9
- package/dist/i18n/index.js +0 -8
- package/dist/itertools/index.d.ts +0 -251
- package/dist/itertools/index.js +0 -434
- package/dist/math/index.d.ts +0 -79
- package/dist/math/index.js +0 -81
- package/dist/mod.d.ts +0 -1
- package/dist/mod.js +0 -1
- package/dist/operators/index.d.ts +0 -148
- package/dist/operators/index.js +0 -325
- package/dist/types.d.ts +0 -19
- package/dist/types.js +0 -1
|
@@ -1,847 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Iteration over objects, arrays, strings, maps, sets and other iterables.
|
|
3
|
+
* Sorted containers, trees, heaps, deques, caches, tries and bisect.
|
|
4
4
|
* @module collections
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export
|
|
10
|
-
export
|
|
11
|
-
export
|
|
12
|
-
export
|
|
13
|
-
export
|
|
14
|
-
export
|
|
15
|
-
export
|
|
16
|
-
export
|
|
17
|
-
export
|
|
18
|
-
export * from './SplayTree.js';
|
|
19
|
-
export * from './Trie.js';
|
|
20
|
-
/** Assigns `key`, defining it where a plain write would set the prototype instead. */
|
|
21
|
-
function setOwn(obj, key, value) {
|
|
22
|
-
if (typeof key === 'string' && key !== '__proto__') {
|
|
23
|
-
obj[key] = value;
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
Object.defineProperty(obj, key, { value, enumerable: true, writable: true, configurable: true });
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
/** `isEmpty` counts declared parameters and keys, which says nothing about these values. */
|
|
30
|
-
function isBlank(x) {
|
|
31
|
-
if (isPlainObject(x))
|
|
32
|
-
return Object.keys(x).length === 0;
|
|
33
|
-
return isEmpty(x) && typeof x !== 'function' && !isDate(x) && !isRegExp(x);
|
|
34
|
-
}
|
|
35
|
-
export function compact(arr) {
|
|
36
|
-
if (!arr)
|
|
37
|
-
return;
|
|
38
|
-
if (Array.isArray(arr))
|
|
39
|
-
return arr.filter((x) => !isBlank(x));
|
|
40
|
-
const result = {};
|
|
41
|
-
for (const key of Object.keys(arr)) {
|
|
42
|
-
if (!isBlank(arr[key])) {
|
|
43
|
-
setOwn(result, key, arr[key]);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return result;
|
|
47
|
-
}
|
|
48
|
-
export function count(obj, func) {
|
|
49
|
-
const counters = {};
|
|
50
|
-
forEach(obj, (value, key) => {
|
|
51
|
-
const result = func(value, key);
|
|
52
|
-
setOwn(counters, result, Object.hasOwn(counters, result) ? counters[result] + 1 : 1);
|
|
53
|
-
});
|
|
54
|
-
return counters;
|
|
55
|
-
}
|
|
56
|
-
export function filter(arr, fn = isNull) {
|
|
57
|
-
if (!arr)
|
|
58
|
-
return;
|
|
59
|
-
const predicate = isFunction(fn) ? fn : isObject(fn) ? matches(fn) : (obj) => get(fn, obj);
|
|
60
|
-
const results = [];
|
|
61
|
-
forEach(arr, (value, key) => {
|
|
62
|
-
if (predicate(value, key, arr))
|
|
63
|
-
results.push(value);
|
|
64
|
-
});
|
|
65
|
-
return results;
|
|
66
|
-
}
|
|
67
|
-
export function find(arr, fn) {
|
|
68
|
-
const it = isFunction(fn) ? fn : isObject(fn) ? matches(fn) : (obj) => get(fn, obj);
|
|
69
|
-
if (Array.isArray(arr)) {
|
|
70
|
-
return arr.find(it);
|
|
71
|
-
}
|
|
72
|
-
else if (isIterable(arr)) {
|
|
73
|
-
for (const [index, value] of enumerate(arr)) {
|
|
74
|
-
if (it(value, index, arr))
|
|
75
|
-
return value;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
else if (isObject(arr)) {
|
|
79
|
-
for (const key of Object.keys(arr)) {
|
|
80
|
-
if (it(arr[key], key, arr)) {
|
|
81
|
-
return arr[key];
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Performs an efficient array insert operation in the given array. If the index or the array is invalid, it just returns the given array.
|
|
88
|
-
*
|
|
89
|
-
* **Note:** Uses the same behavior as `Array.splice`.
|
|
90
|
-
*
|
|
91
|
-
* @param {Array<*>} arr The given array to insert into
|
|
92
|
-
* @param {number} index The index of the array insert operation.
|
|
93
|
-
* @param {*} value The value to insert in the array at the given `index`.
|
|
94
|
-
* @returns {Array<*>} The given array.
|
|
95
|
-
*/
|
|
96
|
-
export function insert(arr, index, value) {
|
|
97
|
-
if (!arr || index < 0)
|
|
98
|
-
return arr;
|
|
99
|
-
arr.splice(index, 0, value);
|
|
100
|
-
return arr;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Creates a function that performs a partial deep comparison between a given object and `shape`, returning `true` if the given object has equivalent property values, else `false`.
|
|
104
|
-
* @example
|
|
105
|
-
```js
|
|
106
|
-
let objects = [
|
|
107
|
-
{ a: 1, b: 2, c: 3 },
|
|
108
|
-
{ a: 4, b: 5, c: 6 }
|
|
109
|
-
]
|
|
110
|
-
|
|
111
|
-
filter(objects, matches({ a: 4, c: 6 }))
|
|
112
|
-
// [{ a: 4, b: 5, c: 6 }]
|
|
113
|
-
```
|
|
114
|
-
* @param shape
|
|
115
|
-
* @returns
|
|
116
|
-
*/
|
|
117
|
-
export function matches(shape) {
|
|
118
|
-
return (obj) => {
|
|
119
|
-
if (!shape || !obj)
|
|
120
|
-
return false;
|
|
121
|
-
const seen = new Map();
|
|
122
|
-
for (const key in shape) {
|
|
123
|
-
if (!isPartialMatch(shape[key], obj[key], seen))
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
return true;
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
function isPartialMatch(shape, value, seen) {
|
|
130
|
-
if (shape === value)
|
|
131
|
-
return true;
|
|
132
|
-
const isList = Array.isArray(shape);
|
|
133
|
-
if (!isList && !isPlainObject(shape))
|
|
134
|
-
return false;
|
|
135
|
-
if (value === null || typeof value !== 'object' || isList !== Array.isArray(value))
|
|
136
|
-
return false;
|
|
137
|
-
const visited = seen.get(shape) ?? new Set();
|
|
138
|
-
if (visited.has(value))
|
|
139
|
-
return true;
|
|
140
|
-
seen.set(shape, visited.add(value));
|
|
141
|
-
return Object.keys(shape).every((key) => isPartialMatch(shape[key], value[key], seen));
|
|
142
|
-
}
|
|
143
|
-
export function forEach(collection, fn) {
|
|
144
|
-
if (collection == null)
|
|
145
|
-
return;
|
|
146
|
-
if (Array.isArray(collection)) {
|
|
147
|
-
for (let i = 0; i < collection.length; i++) {
|
|
148
|
-
const res = fn(collection[i], i, collection);
|
|
149
|
-
if (res === false)
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
else if (isIterable(collection)) {
|
|
154
|
-
for (const [index, value] of enumerate(collection)) {
|
|
155
|
-
const res = fn(value, index, collection);
|
|
156
|
-
if (res === false)
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
for (const key of Object.keys(collection)) {
|
|
162
|
-
const res = fn(collection[key], key, collection);
|
|
163
|
-
if (res === false)
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
export function findLast(arr, fn) {
|
|
169
|
-
let result;
|
|
170
|
-
const it = isFunction(fn) ? fn : isObject(fn) ? matches(fn) : (obj) => get(fn, obj);
|
|
171
|
-
forEachRight(arr, (val, key) => {
|
|
172
|
-
if (it(val, key, arr)) {
|
|
173
|
-
result = val;
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
return result;
|
|
178
|
-
}
|
|
179
|
-
export function forEachRight(collection, fn) {
|
|
180
|
-
if (Array.isArray(collection)) {
|
|
181
|
-
for (let i = collection.length - 1; i >= 0; i--) {
|
|
182
|
-
const value = collection[i];
|
|
183
|
-
const res = fn(value, i, collection);
|
|
184
|
-
if (res === false)
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
else if (isIterable(collection)) {
|
|
189
|
-
const items = Array.from(collection);
|
|
190
|
-
for (let i = items.length - 1; i >= 0; i--) {
|
|
191
|
-
const res = fn(items[i], i, collection);
|
|
192
|
-
if (res === false)
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
else if (isObject(collection)) {
|
|
197
|
-
const keys = Object.keys(collection);
|
|
198
|
-
for (let i = keys.length - 1; i >= 0; i--) {
|
|
199
|
-
const key = keys[i];
|
|
200
|
-
const value = collection[key];
|
|
201
|
-
const res = fn(value, key, collection);
|
|
202
|
-
if (res === false)
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
export function flatten(arr, depth = 1) {
|
|
208
|
-
if (!depth)
|
|
209
|
-
return arr;
|
|
210
|
-
if (Array.isArray(arr))
|
|
211
|
-
return flattenArray(arr, depth, []);
|
|
212
|
-
if (isFlattenable(arr))
|
|
213
|
-
return flattenObj(arr);
|
|
214
|
-
return arr;
|
|
215
|
-
}
|
|
216
|
-
function flattenArray(arr, depth = 1, result = []) {
|
|
217
|
-
for (const value of arr) {
|
|
218
|
-
if (depth && Array.isArray(value)) {
|
|
219
|
-
flattenArray(value, typeof depth === 'number' ? depth - 1 : depth, result);
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
result.push(value);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
return result;
|
|
226
|
-
}
|
|
227
|
-
/** A `Date` or `RegExp` has no keys to walk, so `flatten` keeps it as a leaf. */
|
|
228
|
-
function isFlattenable(x) {
|
|
229
|
-
return Array.isArray(x) || (isObject(x) && !isDate(x) && !isRegExp(x));
|
|
230
|
-
}
|
|
231
|
-
function flattenObj(obj, prefix = '', result = {}, keepNull = false) {
|
|
232
|
-
if (isNull(obj) ? keepNull : !isFlattenable(obj)) {
|
|
233
|
-
setOwn(result, prefix, obj);
|
|
234
|
-
return result;
|
|
235
|
-
}
|
|
236
|
-
if (Array.isArray(obj) || isObject(obj)) {
|
|
237
|
-
for (const i of Object.keys(obj)) {
|
|
238
|
-
let pref = prefix;
|
|
239
|
-
if (Array.isArray(obj)) {
|
|
240
|
-
pref = `${pref}[${i}]`;
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
if (prefix) {
|
|
244
|
-
pref = `${prefix}.${i}`;
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
pref = i;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
flattenObj(obj[i], pref, result, keepNull);
|
|
251
|
-
}
|
|
252
|
-
return result;
|
|
253
|
-
}
|
|
254
|
-
return result;
|
|
255
|
-
}
|
|
256
|
-
export function map(arr, fn) {
|
|
257
|
-
const it = isFunction(fn) ? fn : (obj) => get(fn, obj);
|
|
258
|
-
if (Array.isArray(arr)) {
|
|
259
|
-
return arr.map((x, i) => it(x, i, arr));
|
|
260
|
-
}
|
|
261
|
-
if (isIterable(arr)) {
|
|
262
|
-
return Array.from(arr, (x, i) => it(x, i, arr));
|
|
263
|
-
}
|
|
264
|
-
if (isObject(arr)) {
|
|
265
|
-
return Object.keys(arr).map((key) => it(arr[key], key, arr));
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
export function pick(obj, paths) {
|
|
269
|
-
if (!obj)
|
|
270
|
-
return {};
|
|
271
|
-
const result = {};
|
|
272
|
-
if (isFunction(paths)) {
|
|
273
|
-
for (const key of Object.keys(obj)) {
|
|
274
|
-
if (paths(obj[key], key)) {
|
|
275
|
-
setOwn(result, key, obj[key]);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
return result;
|
|
279
|
-
}
|
|
280
|
-
for (const path of paths) {
|
|
281
|
-
const key = typeof path === 'symbol' ? path : String(path);
|
|
282
|
-
const value = get(path, obj);
|
|
283
|
-
if (key !== '__proto__' && (value !== undefined || key in Object(obj)))
|
|
284
|
-
result[key] = value;
|
|
285
|
-
}
|
|
286
|
-
return result;
|
|
287
|
-
}
|
|
288
|
-
export function omit(obj, paths) {
|
|
289
|
-
if (!obj)
|
|
290
|
-
return {};
|
|
291
|
-
const result = {};
|
|
292
|
-
if (isFunction(paths)) {
|
|
293
|
-
for (const key of Object.keys(obj)) {
|
|
294
|
-
if (!paths(obj[key], key)) {
|
|
295
|
-
setOwn(result, key, obj[key]);
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
return result;
|
|
299
|
-
}
|
|
300
|
-
const kept = { ...obj };
|
|
301
|
-
for (const key of paths) {
|
|
302
|
-
delete kept[key];
|
|
303
|
-
}
|
|
304
|
-
return kept;
|
|
305
|
-
}
|
|
306
|
-
export function findIndex(obj, fn, start = 0) {
|
|
307
|
-
if (!obj)
|
|
308
|
-
return -1;
|
|
309
|
-
const length = obj.length;
|
|
310
|
-
if (length && start < 0) {
|
|
311
|
-
start = Math.max(start + length, 0);
|
|
312
|
-
}
|
|
313
|
-
if (!length || start >= length)
|
|
314
|
-
return -1;
|
|
315
|
-
const it = isFunction(fn) ? fn : isObject(fn) ? matches(fn) : (obj) => get(fn, obj);
|
|
316
|
-
for (; start < length; start++) {
|
|
317
|
-
if (it(obj[start], start, obj))
|
|
318
|
-
return start;
|
|
319
|
-
}
|
|
320
|
-
return -1;
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* This method is like {@link findIndex} except that it searches for a given value directly, instead of using a predicate function.
|
|
324
|
-
* @param {Array} obj The array to inspect.
|
|
325
|
-
* @param {*} value The value to find
|
|
326
|
-
* @param {number} [start=0] The index to search from.
|
|
327
|
-
* @returns {number} The index of the found value, else -1
|
|
328
|
-
* @example
|
|
329
|
-
```js
|
|
330
|
-
indexOf([1, 2, 1, 2], 2)
|
|
331
|
-
// 1
|
|
332
|
-
|
|
333
|
-
// Search from a `start` index.
|
|
334
|
-
indexOf([1, 2, 1, 2], 2, 2)
|
|
335
|
-
// 3
|
|
336
|
-
```
|
|
337
|
-
* @see {@link findIndex}
|
|
338
|
-
* @see {@link lastIndexOf}
|
|
339
|
-
*/
|
|
340
|
-
export function indexOf(obj, value, start = 0) {
|
|
341
|
-
if (!obj)
|
|
342
|
-
return -1;
|
|
343
|
-
const op = call(obj, 'indexOf', value, start);
|
|
344
|
-
if (op != null)
|
|
345
|
-
return op;
|
|
346
|
-
const length = obj.length;
|
|
347
|
-
if (length && start < 0) {
|
|
348
|
-
start = Math.max(start + length, 0);
|
|
349
|
-
}
|
|
350
|
-
if (!length || start >= length)
|
|
351
|
-
return -1;
|
|
352
|
-
for (; start < length; start++) {
|
|
353
|
-
if (eq(value, obj[start]))
|
|
354
|
-
return start;
|
|
355
|
-
}
|
|
356
|
-
return -1;
|
|
357
|
-
}
|
|
358
|
-
export function findLastIndex(arr, fn, start) {
|
|
359
|
-
if (arr == null)
|
|
360
|
-
return -1;
|
|
361
|
-
const length = arr.length;
|
|
362
|
-
start = Math.min(start ?? length - 1, length - 1);
|
|
363
|
-
if (!length || start < 0)
|
|
364
|
-
return -1;
|
|
365
|
-
const it = isFunction(fn) ? fn : isObject(fn) ? matches(fn) : (obj) => get(fn, obj);
|
|
366
|
-
for (; start >= 0; start--) {
|
|
367
|
-
if (it(arr[start], start, arr))
|
|
368
|
-
return start;
|
|
369
|
-
}
|
|
370
|
-
return -1;
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* This method is like {@link indexOf} except that it iterates the collection from right to left.
|
|
374
|
-
* @param {Array} obj The array to inspect.
|
|
375
|
-
* @param {*} value The value to find
|
|
376
|
-
* @param {number} [start] The index to search from.
|
|
377
|
-
* @returns {number} The index of the found value, else -1
|
|
378
|
-
* @example
|
|
379
|
-
```js
|
|
380
|
-
lastIndexOf([1, 2, 1, 2], 2)
|
|
381
|
-
// 3
|
|
382
|
-
|
|
383
|
-
// Search from the `fromIndex`.
|
|
384
|
-
lastIndexOf([1, 2, 1, 2], 2, 2)
|
|
385
|
-
// 1
|
|
386
|
-
```
|
|
387
|
-
* @see {@link findLastIndex}
|
|
388
|
-
* @see {@link indexOf}
|
|
389
|
-
*/
|
|
390
|
-
export function lastIndexOf(obj, value, start) {
|
|
391
|
-
if (obj == null)
|
|
392
|
-
return -1;
|
|
393
|
-
const op = call(obj, 'lastIndexOf', ...(start === undefined ? [value] : [value, start]));
|
|
394
|
-
if (op != null)
|
|
395
|
-
return op;
|
|
396
|
-
const length = obj.length;
|
|
397
|
-
start = Math.min(start ?? length - 1, length - 1);
|
|
398
|
-
if (!length || start < 0)
|
|
399
|
-
return -1;
|
|
400
|
-
for (; start >= 0; start--) {
|
|
401
|
-
if (eq(value, obj[start]))
|
|
402
|
-
return start;
|
|
403
|
-
}
|
|
404
|
-
return -1;
|
|
405
|
-
}
|
|
406
|
-
export function clone(value, deep = false) {
|
|
407
|
-
return cloneValue(value, deep, new Map());
|
|
408
|
-
}
|
|
409
|
-
function cloneValue(value, deep, copies) {
|
|
410
|
-
if (copies.has(value))
|
|
411
|
-
return copies.get(value);
|
|
412
|
-
if (value instanceof ArrayBuffer)
|
|
413
|
-
return value.slice(0);
|
|
414
|
-
if (ArrayBuffer.isView(value)) {
|
|
415
|
-
return cloneTypedArray(value, deep);
|
|
416
|
-
}
|
|
417
|
-
if (isObject(value) && isFunction(value.clone)) {
|
|
418
|
-
return value.clone();
|
|
419
|
-
}
|
|
420
|
-
if (Array.isArray(value) || hasElements(value)) {
|
|
421
|
-
return cloneArray(value, deep, copies);
|
|
422
|
-
}
|
|
423
|
-
if (value?.constructor === Map) {
|
|
424
|
-
const map = new Map();
|
|
425
|
-
copies.set(value, map);
|
|
426
|
-
for (const [key, item] of value)
|
|
427
|
-
map.set(key, deep ? cloneValue(item, deep, copies) : item);
|
|
428
|
-
return map;
|
|
429
|
-
}
|
|
430
|
-
if (value?.constructor === Set) {
|
|
431
|
-
const set = new Set();
|
|
432
|
-
copies.set(value, set);
|
|
433
|
-
for (const item of value)
|
|
434
|
-
set.add(deep ? cloneValue(item, deep, copies) : item);
|
|
435
|
-
return set;
|
|
436
|
-
}
|
|
437
|
-
if (isObject(value)) {
|
|
438
|
-
if (isDate(value))
|
|
439
|
-
return new Date(value.getTime());
|
|
440
|
-
if (isRegExp(value)) {
|
|
441
|
-
const regex = new RegExp(value.source, value.flags);
|
|
442
|
-
regex.lastIndex = value.lastIndex;
|
|
443
|
-
return regex;
|
|
444
|
-
}
|
|
445
|
-
const copy = {};
|
|
446
|
-
copies.set(value, copy);
|
|
447
|
-
for (const key in value) {
|
|
448
|
-
if (deep) {
|
|
449
|
-
setOwn(copy, key, cloneValue(value[key], deep, copies));
|
|
450
|
-
}
|
|
451
|
-
else {
|
|
452
|
-
setOwn(copy, key, value[key]);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
return copy;
|
|
456
|
-
}
|
|
457
|
-
return value;
|
|
458
|
-
}
|
|
459
|
-
/** `isArrayLike` accepts any numeric `length`, so this also looks for the elements. */
|
|
460
|
-
function hasElements(x) {
|
|
461
|
-
return isArrayLike(x) && (isIterable(x) || x.length - 1 in x);
|
|
462
|
-
}
|
|
463
|
-
/**
|
|
464
|
-
* Clones an array. If `deep` is `false` (default) the clone will be shallow. Otherwise {@link https://developer.mozilla.org/en-US/docs/Web/API/structuredClone structuredClone} is used.
|
|
465
|
-
* @param arr The array to clone
|
|
466
|
-
* @param [deep=false] Creates a deep clone using `structuredClone` if true.
|
|
467
|
-
* @returns The new array
|
|
468
|
-
* @see {@link clone}
|
|
469
|
-
*/
|
|
470
|
-
function cloneArray(arr, deep, copies) {
|
|
471
|
-
if (!deep)
|
|
472
|
-
return Array.from(arr);
|
|
473
|
-
try {
|
|
474
|
-
return structuredClone(arr);
|
|
475
|
-
}
|
|
476
|
-
catch {
|
|
477
|
-
const copy = Array.from(arr);
|
|
478
|
-
copies.set(arr, copy);
|
|
479
|
-
copy.forEach((item, index) => {
|
|
480
|
-
copy[index] = cloneValue(item, deep, copies);
|
|
481
|
-
});
|
|
482
|
-
return copy;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
/**
|
|
486
|
-
* Clones a typed array. If `deep` is `false` (default) the clone will be shallow. Otherwise {@link https://developer.mozilla.org/en-US/docs/Web/API/structuredClone structuredClone} is used.
|
|
487
|
-
* @param arr The array to clone
|
|
488
|
-
* @param [deep=false] Creates a deep clone using `structuredClone` if true.
|
|
489
|
-
* @returns The new array
|
|
490
|
-
* @see {@link clone}
|
|
491
|
-
*/
|
|
492
|
-
function cloneTypedArray(typedArray, isDeep = false) {
|
|
493
|
-
if (typedArray instanceof DataView) {
|
|
494
|
-
const viewed = isDeep ? typedArray.buffer.slice(0) : typedArray.buffer;
|
|
495
|
-
return new DataView(viewed, typedArray.byteOffset, typedArray.byteLength);
|
|
496
|
-
}
|
|
497
|
-
const buffer = isDeep ? structuredClone(typedArray) : typedArray.buffer;
|
|
498
|
-
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
|
|
499
|
-
}
|
|
500
|
-
export function uniq(arr, fn = identity) {
|
|
501
|
-
const keys = new Set();
|
|
502
|
-
const results = [];
|
|
503
|
-
const it = isFunction(fn) ? fn : (x) => get(fn, x);
|
|
504
|
-
for (const x of arr ?? []) {
|
|
505
|
-
const key = it(x);
|
|
506
|
-
if (keys.has(key))
|
|
507
|
-
continue;
|
|
508
|
-
keys.add(key);
|
|
509
|
-
results.push(Object.is(x, -0) ? 0 : x);
|
|
510
|
-
}
|
|
511
|
-
return results;
|
|
512
|
-
}
|
|
513
|
-
export function sortedUniq(arr, fn = identity) {
|
|
514
|
-
const it = isFunction(fn) ? fn : (x) => get(fn, x);
|
|
515
|
-
return uniq(arr, it).sort((x, y) => compare(it(x), it(y)));
|
|
516
|
-
}
|
|
517
|
-
/** True for an object made by `{}`, `JSON.parse` or `Object.create(null)`, in any realm. */
|
|
518
|
-
function isPlainObject(x) {
|
|
519
|
-
if (Object.prototype.toString.call(x) !== '[object Object]')
|
|
520
|
-
return false;
|
|
521
|
-
const proto = Object.getPrototypeOf(x);
|
|
522
|
-
return proto === null || Object.getPrototypeOf(proto) === null;
|
|
523
|
-
}
|
|
524
|
-
function baseMergeDeep(obj, source, key, stack, copies, merged) {
|
|
525
|
-
const objValue = obj[key];
|
|
526
|
-
const srcValue = source[key];
|
|
527
|
-
const stacked = stack.get(srcValue);
|
|
528
|
-
if (stacked) {
|
|
529
|
-
obj[key] = stacked;
|
|
530
|
-
return;
|
|
531
|
-
}
|
|
532
|
-
let newValue;
|
|
533
|
-
let isCommon = newValue === undefined;
|
|
534
|
-
let isCopy = false;
|
|
535
|
-
const isArray = Array.isArray(srcValue);
|
|
536
|
-
const isTyped = ArrayBuffer.isView(srcValue);
|
|
537
|
-
if (isArray || isTyped) {
|
|
538
|
-
if (Array.isArray(objValue)) {
|
|
539
|
-
newValue = objValue;
|
|
540
|
-
}
|
|
541
|
-
else if (hasElements(objValue)) {
|
|
542
|
-
newValue = Array.from(objValue);
|
|
543
|
-
}
|
|
544
|
-
else if (isTyped) {
|
|
545
|
-
isCommon = false;
|
|
546
|
-
newValue = cloneTypedArray(srcValue, true);
|
|
547
|
-
}
|
|
548
|
-
else {
|
|
549
|
-
newValue = [];
|
|
550
|
-
isCopy = true;
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
else if (isPlainObject(srcValue)) {
|
|
554
|
-
isCopy = !isObject(objValue);
|
|
555
|
-
newValue = isCopy ? {} : objValue;
|
|
556
|
-
}
|
|
557
|
-
else {
|
|
558
|
-
isCommon = false;
|
|
559
|
-
newValue = srcValue;
|
|
560
|
-
}
|
|
561
|
-
if (isCopy && copies.has(srcValue)) {
|
|
562
|
-
obj[key] = copies.get(srcValue);
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
const targets = merged.get(srcValue) ?? new WeakSet();
|
|
566
|
-
if (isCommon && !targets.has(newValue)) {
|
|
567
|
-
merged.set(srcValue, targets.add(newValue));
|
|
568
|
-
stack.set(srcValue, newValue);
|
|
569
|
-
baseMerge(newValue, srcValue, stack, copies, merged);
|
|
570
|
-
stack.delete(srcValue);
|
|
571
|
-
}
|
|
572
|
-
if (isCopy)
|
|
573
|
-
copies.set(srcValue, newValue);
|
|
574
|
-
obj[key] = newValue;
|
|
575
|
-
}
|
|
576
|
-
function baseMerge(obj, source, stack, copies, merged) {
|
|
577
|
-
if (obj === source)
|
|
578
|
-
return obj;
|
|
579
|
-
for (const key of Object.keys(source)) {
|
|
580
|
-
if (key === '__proto__')
|
|
581
|
-
continue;
|
|
582
|
-
const srcValue = source[key];
|
|
583
|
-
const objValue = obj[key];
|
|
584
|
-
if (typeof srcValue === 'object' && srcValue !== null) {
|
|
585
|
-
baseMergeDeep(obj, source, key, stack, copies, merged);
|
|
586
|
-
}
|
|
587
|
-
else {
|
|
588
|
-
if (srcValue !== undefined && objValue !== srcValue) {
|
|
589
|
-
obj[key] = srcValue;
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* Recursively merges own enumerable string keyed properties of source objects into the destination object. Source properties that resolve to `undefined` are skipped if a destination value exists. Array and plain object properties are merged recursively. Other objects and value types are overridden by assignment. Source objects are applied from left to right. Subsequent sources overwrite property assignments of previous sources.
|
|
596
|
-
*
|
|
597
|
-
* Note: this method mutates `object`
|
|
598
|
-
*
|
|
599
|
-
*
|
|
600
|
-
* @param {Object} object The destination object.
|
|
601
|
-
* @param {...Object} sources The source objects.
|
|
602
|
-
* @returns Returns `object`.
|
|
603
|
-
*
|
|
604
|
-
* @example
|
|
605
|
-
```js
|
|
606
|
-
let object = {
|
|
607
|
-
'a': [{ 'b': 2 }, { 'd': 4 }]
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
let other = {
|
|
611
|
-
'a': [{ 'c': 3 }, { 'e': 5 }]
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
merge(object, other)
|
|
615
|
-
// { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
|
|
616
|
-
```
|
|
617
|
-
*/
|
|
618
|
-
export function merge(object, ...sources) {
|
|
619
|
-
for (const source of sources) {
|
|
620
|
-
if (source != null)
|
|
621
|
-
baseMerge(object, source, new WeakMap(), new WeakMap(), new WeakMap());
|
|
622
|
-
}
|
|
623
|
-
return object;
|
|
624
|
-
}
|
|
625
|
-
/**
|
|
626
|
-
* Assigns own and inherited enumerable string keyed properties of source objects to the destination object for all destination properties that resolve to `undefined`. Source objects are applied from left to right. Once a property is set, additional values of the same property are ignored.
|
|
627
|
-
* **Note:** This method mutates `object`.
|
|
628
|
-
|
|
629
|
-
* @param {Object} object The destination object.
|
|
630
|
-
* @param {...Object} [sources] The source objects.
|
|
631
|
-
* @returns Returns `object`.
|
|
632
|
-
* @example
|
|
633
|
-
```js
|
|
634
|
-
defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 })
|
|
635
|
-
// { 'a': 1, 'b': 2 }
|
|
636
|
-
```
|
|
637
|
-
*/
|
|
638
|
-
export function defaults(object, ...sources) {
|
|
639
|
-
for (const source of sources) {
|
|
640
|
-
for (const key in source) {
|
|
641
|
-
if (object[key] === undefined) {
|
|
642
|
-
object[key] = source[key];
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
return object;
|
|
647
|
-
}
|
|
648
|
-
/**
|
|
649
|
-
* Returns a generator of array values not included in the other given arrays using a `Set` for equality comparisons. The order and references of result values are not guaranteed.
|
|
650
|
-
* @param args The initial arrays
|
|
651
|
-
* @example
|
|
652
|
-
```js
|
|
653
|
-
[...difference([2, 1], [2, 3])]
|
|
654
|
-
// [1]
|
|
655
|
-
```
|
|
656
|
-
* @see {@link union}
|
|
657
|
-
* @see {@link intersection}
|
|
658
|
-
*/
|
|
659
|
-
export function* difference(...args) {
|
|
660
|
-
const sets = args.map((arr) => new Set(arr));
|
|
661
|
-
const setA = sets[0] ?? new Set();
|
|
662
|
-
for (let i = 1; i < sets.length; i++) {
|
|
663
|
-
for (const x of sets[i].values()) {
|
|
664
|
-
setA.delete(x);
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
for (const x of setA.values()) {
|
|
668
|
-
yield x;
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
/**
|
|
672
|
-
* Creates a generator of unique values that are included in all given arrays.
|
|
673
|
-
* @param args The arrays to inspect
|
|
674
|
-
* @example
|
|
675
|
-
```js
|
|
676
|
-
[...intersection([2, 1], [2, 3])]
|
|
677
|
-
// [2]
|
|
678
|
-
```
|
|
679
|
-
* @see {@link difference}
|
|
680
|
-
* @see {@link union}
|
|
681
|
-
*/
|
|
682
|
-
export function* intersection(...args) {
|
|
683
|
-
const sets = args.map((arr) => new Set(arr));
|
|
684
|
-
// build a counter map to find items in all
|
|
685
|
-
const results = new Map();
|
|
686
|
-
const total = sets.length;
|
|
687
|
-
for (let i = 0; i < total; i++) {
|
|
688
|
-
for (const x of sets[i].values()) {
|
|
689
|
-
const count = results.get(x) || 0;
|
|
690
|
-
results.set(x, count + 1);
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
for (const [key, value] of results.entries()) {
|
|
694
|
-
if (value === total)
|
|
695
|
-
yield key;
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
/**
|
|
699
|
-
* Creates a generator of unique values from all given arrays using `Set` for equality comparisons.
|
|
700
|
-
* @param args The arrays to perform union on.
|
|
701
|
-
* @example
|
|
702
|
-
```js
|
|
703
|
-
[...union([2], [1, 2])]
|
|
704
|
-
// [2, 1]
|
|
705
|
-
```
|
|
706
|
-
* @see {@link difference}
|
|
707
|
-
* @see {@link intersection}
|
|
708
|
-
*/
|
|
709
|
-
export function* union(...args) {
|
|
710
|
-
const results = new Set();
|
|
711
|
-
for (const arr of args) {
|
|
712
|
-
for (const item of arr ?? []) {
|
|
713
|
-
results.add(item);
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
for (const item of results.values()) {
|
|
717
|
-
yield item;
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
export function groupBy(arr, func = identity) {
|
|
721
|
-
const useKey = isFunction(func) ? func : (obj) => get(func, obj);
|
|
722
|
-
const results = {};
|
|
723
|
-
forEach(arr, (value) => {
|
|
724
|
-
const groupKey = useKey(value);
|
|
725
|
-
if (!Object.hasOwn(results, groupKey))
|
|
726
|
-
setOwn(results, groupKey, []);
|
|
727
|
-
results[groupKey].push(value);
|
|
728
|
-
});
|
|
729
|
-
return results;
|
|
730
|
-
}
|
|
731
|
-
export function groupByMap(arr, func = identity) {
|
|
732
|
-
const results = new Map();
|
|
733
|
-
const useKey = isFunction(func) ? func : (obj) => get(func, obj);
|
|
734
|
-
forEach(arr, (value) => {
|
|
735
|
-
const groupKey = useKey(value);
|
|
736
|
-
const values = results.get(groupKey) || [];
|
|
737
|
-
values.push(value);
|
|
738
|
-
results.set(groupKey, values);
|
|
739
|
-
});
|
|
740
|
-
return results;
|
|
741
|
-
}
|
|
742
|
-
export function remove(arr, func) {
|
|
743
|
-
const it = isFunction(func)
|
|
744
|
-
? func
|
|
745
|
-
: Array.isArray(func)
|
|
746
|
-
? (x) => func.includes(x)
|
|
747
|
-
: (x) => func === x;
|
|
748
|
-
return arr.filter((x, i) => !it(x, i, arr));
|
|
749
|
-
}
|
|
750
|
-
/**
|
|
751
|
-
* Returns the index of `x` in a **sorted** array if found, in `O(log n)` using binary search.
|
|
752
|
-
* If the element is not found, returns `-n - 1`, where `n` is the index to insert `x` at.
|
|
753
|
-
* @param arr The sorted array
|
|
754
|
-
* @param x The element to find
|
|
755
|
-
* @param lo The starting index
|
|
756
|
-
* @param hi The end index to search within
|
|
757
|
-
* @param comp The compare function to check for `x`
|
|
758
|
-
* @returns {number} The index if the element is found or a negative integer.
|
|
759
|
-
*/
|
|
760
|
-
export function binarySearch(arr, x, lo = 0, hi, comp = compare) {
|
|
761
|
-
hi ??= arr.length - 1;
|
|
762
|
-
while (lo < hi) {
|
|
763
|
-
const mid = (lo + hi) >> 1;
|
|
764
|
-
const check = comp(x, arr[mid]);
|
|
765
|
-
if (check === 0)
|
|
766
|
-
return mid;
|
|
767
|
-
if (check > 0)
|
|
768
|
-
lo = mid + 1;
|
|
769
|
-
else
|
|
770
|
-
hi = mid - 1;
|
|
771
|
-
}
|
|
772
|
-
const check = lo <= hi ? comp(x, arr[lo]) : -1;
|
|
773
|
-
if (check === 0)
|
|
774
|
-
return lo;
|
|
775
|
-
// Returns (-n - 1) where n is the insertion point for new element in the range
|
|
776
|
-
return check > 0 ? -lo - 2 : -lo - 1;
|
|
777
|
-
}
|
|
778
|
-
/**
|
|
779
|
-
* Returns an insertion index which comes after any existing entries of `x` in a **sorted** array, using binary search.
|
|
780
|
-
* @param arr The sorted array
|
|
781
|
-
* @param x The element to find
|
|
782
|
-
* @param lo The starting index
|
|
783
|
-
* @param hi The end index to search within
|
|
784
|
-
* @param comp The compare function to check for `x`
|
|
785
|
-
* @returns {number}
|
|
786
|
-
*/
|
|
787
|
-
export function bisect(arr, x, lo = 0, hi, comp = compare) {
|
|
788
|
-
hi ??= arr.length;
|
|
789
|
-
while (lo < hi) {
|
|
790
|
-
const mid = (lo + hi) >> 1;
|
|
791
|
-
const check = comp(x, arr[mid]);
|
|
792
|
-
if (check >= 0)
|
|
793
|
-
lo = mid + 1;
|
|
794
|
-
else
|
|
795
|
-
hi = mid;
|
|
796
|
-
}
|
|
797
|
-
return lo;
|
|
798
|
-
}
|
|
799
|
-
/**
|
|
800
|
-
* Returns an insertion index which comes before any existing entries of `x` in a **sorted** array, using binary search.
|
|
801
|
-
* @param arr The sorted array
|
|
802
|
-
* @param x The element to find
|
|
803
|
-
* @param lo The starting index
|
|
804
|
-
* @param hi The end index to search within
|
|
805
|
-
* @param comp The compare function to check for `x`
|
|
806
|
-
* @returns {number}
|
|
807
|
-
*/
|
|
808
|
-
export function bisectLeft(arr, x, lo = 0, hi, comp = compare) {
|
|
809
|
-
hi ??= arr.length;
|
|
810
|
-
while (lo < hi) {
|
|
811
|
-
const mid = (lo + hi) >> 1;
|
|
812
|
-
const check = comp(x, arr[mid]);
|
|
813
|
-
if (check <= 0)
|
|
814
|
-
hi = mid;
|
|
815
|
-
else
|
|
816
|
-
lo = mid + 1;
|
|
817
|
-
}
|
|
818
|
-
return lo;
|
|
819
|
-
}
|
|
820
|
-
/**
|
|
821
|
-
* Runs {@link bisect} first to locate an insertion point, and inserts the value `x` in the sorted array after any existing entries of `x` to maintain sort order.
|
|
822
|
-
* Please note this method is `O(n)` because insertion resizes the array.
|
|
823
|
-
* @param arr The array to insert into
|
|
824
|
-
* @param x The element to insert
|
|
825
|
-
* @param lo The starting index
|
|
826
|
-
* @param hi The end index to search within
|
|
827
|
-
* @param comp The compare function to check for `x`
|
|
828
|
-
* @returns {Array}
|
|
829
|
-
*/
|
|
830
|
-
export function insort(arr, x, lo = 0, hi, comp = compare) {
|
|
831
|
-
const index = bisect(arr, x, lo, hi, comp);
|
|
832
|
-
return insert(arr, index, x);
|
|
833
|
-
}
|
|
834
|
-
/**
|
|
835
|
-
* Runs {@link bisectLeft} first to locate an insertion point, and inserts the value `x` in the sorted array before any existing entries of `x` to maintain sort order.
|
|
836
|
-
* Please note this method is `O(n)` because insertion resizes the array.
|
|
837
|
-
* @param arr The array to insert into
|
|
838
|
-
* @param x The element to insert
|
|
839
|
-
* @param lo The starting index
|
|
840
|
-
* @param hi The end index to search within
|
|
841
|
-
* @param comp The compare function to check for `x`
|
|
842
|
-
* @returns {Array}
|
|
843
|
-
*/
|
|
844
|
-
export function insortLeft(arr, x, lo = 0, hi, comp = compare) {
|
|
845
|
-
const index = bisectLeft(arr, x, lo, hi, comp);
|
|
846
|
-
return insert(arr, index, x);
|
|
847
|
-
}
|
|
6
|
+
export { entries, includes, isEmpty, keys, size, values } from './entries.js';
|
|
7
|
+
export { countBy, groupBy, keyBy, maxBy, meanBy, minBy, orderBy, partition, sortBy, sumBy } from './group.js';
|
|
8
|
+
export { every, filter, find, findLast, flatMap, forEach, forEachRight, map, reduce, reduceRight, reject, some } from './iterate.js';
|
|
9
|
+
export { binarySearch, bisect, bisectLeft, bisectRight, insort, insortLeft } from './bisect.js';
|
|
10
|
+
export { Deque } from './deque.js';
|
|
11
|
+
export { FrozenSet } from './frozen-set.js';
|
|
12
|
+
export { Heap } from './heap.js';
|
|
13
|
+
export { LRUCache } from './lru-cache.js';
|
|
14
|
+
export { SortedMap } from './sorted-map.js';
|
|
15
|
+
export { SortedSet } from './sorted-set.js';
|
|
16
|
+
export { SplayTree } from './splay-tree.js';
|
|
17
|
+
export { Trie } from './trie.js';
|