@bodil/monkey-business 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/array.d.ts +59 -0
- package/dist/array.js +100 -0
- package/dist/array.js.map +1 -0
- package/dist/index.d.ts +36 -136
- package/dist/index.js +37 -207
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +32 -3
- package/dist/index.test.js.map +1 -1
- package/dist/iterator.d.ts +78 -0
- package/dist/iterator.js +176 -0
- package/dist/iterator.js.map +1 -0
- package/dist/map.d.ts +19 -0
- package/dist/map.js +31 -0
- package/dist/map.js.map +1 -0
- package/dist/object.d.ts +12 -0
- package/dist/object.js +17 -0
- package/dist/object.js.map +1 -0
- package/dist/weakmap.d.ts +19 -0
- package/dist/weakmap.js +31 -0
- package/dist/weakmap.js.map +1 -0
- package/package.json +71 -18
- package/src/array.ts +128 -0
- package/src/es-iterator-helpers.d.ts +24 -0
- package/src/index.test.ts +39 -7
- package/src/index.ts +78 -407
- package/src/iterator.ts +223 -0
- package/src/map.ts +37 -0
- package/src/object.ts +21 -0
- package/src/weakmap.ts +37 -0
package/src/index.ts
CHANGED
|
@@ -1,37 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-this-alias */
|
|
3
|
-
// deno-lint-ignore-file no-this-alias
|
|
4
|
-
|
|
5
|
-
import { None, Option, Some } from "@bodil/opt";
|
|
6
|
-
import { type OrderFn, bisectHigh, bisectLow } from "@bodil/core/order";
|
|
1
|
+
import type { OrderFn } from "@bodil/core/order";
|
|
7
2
|
import type { Present } from "@bodil/core/types";
|
|
8
|
-
import {
|
|
3
|
+
import type { Option } from "@bodil/opt";
|
|
9
4
|
import defineProperties from "define-properties";
|
|
10
5
|
import shimUnscopables from "es-shim-unscopables";
|
|
11
6
|
|
|
12
|
-
import "
|
|
13
|
-
import "
|
|
14
|
-
import "
|
|
7
|
+
import * as array from "./array";
|
|
8
|
+
import * as iterator from "./iterator";
|
|
9
|
+
import * as map from "./map";
|
|
10
|
+
import * as object from "./object";
|
|
11
|
+
import * as weakmap from "./weakmap";
|
|
15
12
|
|
|
16
13
|
declare global {
|
|
17
14
|
/**
|
|
18
15
|
* Added methods on the {@link Object} global object.
|
|
19
16
|
*/
|
|
20
17
|
interface ObjectConstructor {
|
|
21
|
-
/**
|
|
22
|
-
* Checked key lookup. Returns {@link None} if a key isn't present.
|
|
23
|
-
* Returns a {@link Some} if the key is present, even if the value is
|
|
24
|
-
* `undefined`.
|
|
25
|
-
*/
|
|
18
|
+
/** {@inheritDoc object.get} */
|
|
26
19
|
get<O extends object, K extends keyof O>(obj: O, key: K): Option<O[K]>;
|
|
27
20
|
|
|
28
|
-
/**
|
|
29
|
-
* Create a new object by mapping an existing object's `Object.entries`
|
|
30
|
-
* through a function.
|
|
31
|
-
*/
|
|
21
|
+
/** {@inheritDoc object.mapEntries} */
|
|
32
22
|
mapEntries<A, B>(
|
|
33
23
|
obj: Record<string, A>,
|
|
34
|
-
fn: (entry: [key: string, value: A]) => [string, B]
|
|
24
|
+
fn: (entry: [key: string, value: A]) => [string, B],
|
|
35
25
|
): Record<string, B>;
|
|
36
26
|
}
|
|
37
27
|
|
|
@@ -39,19 +29,13 @@ declare global {
|
|
|
39
29
|
* Added methods on {@link Map}s.
|
|
40
30
|
*/
|
|
41
31
|
interface Map<K, V> {
|
|
42
|
-
/**
|
|
43
|
-
* If `key` exists in the map, return the value associated with it.
|
|
44
|
-
* Otherwise, call `defaultValue()` to create a new value, insert that
|
|
45
|
-
* into the map under `key`, and return it.
|
|
46
|
-
*/
|
|
32
|
+
/** {@inheritDoc map.getOrInsertComputed} */
|
|
47
33
|
getOrInsertComputed(key: K, defaultValue: (key: K) => V): V;
|
|
48
34
|
|
|
49
|
-
/**
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
* @see {@link Map.delete}
|
|
54
|
-
*/
|
|
35
|
+
/** {@inheritDoc map.getOrSet} */
|
|
36
|
+
getOrSet(key: K, defaultValue: (key: K) => V): V;
|
|
37
|
+
|
|
38
|
+
/** {@inheritDoc map.remove} */
|
|
55
39
|
remove(key: K): Option<V>;
|
|
56
40
|
}
|
|
57
41
|
|
|
@@ -59,19 +43,13 @@ declare global {
|
|
|
59
43
|
* Added methods on {@link WeakMap}s.
|
|
60
44
|
*/
|
|
61
45
|
interface WeakMap<K extends WeakKey, V> {
|
|
62
|
-
/**
|
|
63
|
-
* If `key` exists in the map, return the value associated with it.
|
|
64
|
-
* Otherwise, call `defaultValue()` to create a new value, insert that
|
|
65
|
-
* into the map under `key`, and return it.
|
|
66
|
-
*/
|
|
46
|
+
/** {@inheritDoc weakmap.getOrInsertComputed} */
|
|
67
47
|
getOrInsertComputed(key: K, defaultValue: (key: K) => V): V;
|
|
68
48
|
|
|
69
|
-
/**
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
* @see {@link WeakMap.delete}
|
|
74
|
-
*/
|
|
49
|
+
/** {@inheritDoc weakmap.getOrSet} */
|
|
50
|
+
getOrSet(key: K, defaultValue: (key: K) => V): V;
|
|
51
|
+
|
|
52
|
+
/** {@inheritDoc weakmap.remove} */
|
|
75
53
|
remove(key: K): Option<V>;
|
|
76
54
|
}
|
|
77
55
|
|
|
@@ -79,69 +57,31 @@ declare global {
|
|
|
79
57
|
* Added methods on {@link Array}s.
|
|
80
58
|
*/
|
|
81
59
|
interface Array<T> {
|
|
82
|
-
/**
|
|
83
|
-
* Insert `value` at `index` in the array.
|
|
84
|
-
*/
|
|
60
|
+
/** {@inheritDoc array.insert} */
|
|
85
61
|
insert(value: T, index: number): Array<T>;
|
|
86
62
|
|
|
87
|
-
/**
|
|
88
|
-
* Insert `value` into the array at the correct position according to
|
|
89
|
-
* the ordering function `cmp`. The array must already be ordered
|
|
90
|
-
* accordingly.
|
|
91
|
-
*
|
|
92
|
-
* If `duplicates` is `"low"`, the correct position in case of
|
|
93
|
-
* duplicates is considered to be the index of the first occurrence of a
|
|
94
|
-
* duplicate. If it is `"high"`, which is the default, the correct
|
|
95
|
-
* position is considered to be the index after the last occurrence of a
|
|
96
|
-
* duplicate.
|
|
97
|
-
*/
|
|
63
|
+
/** {@inheritDoc array.insertOrdered} */
|
|
98
64
|
insertOrdered(value: T, cmp: OrderFn<T>, duplicates?: "low" | "high"): Array<T>;
|
|
99
65
|
|
|
100
|
-
/**
|
|
101
|
-
* Remove the first occurrence of a given value from an array.
|
|
102
|
-
*
|
|
103
|
-
* Returns an {@link Option} containing the removed value, or {@link None} if
|
|
104
|
-
* no matches were found.
|
|
105
|
-
*/
|
|
66
|
+
/** {@inheritDoc array.remove} */
|
|
106
67
|
remove(value: T): Option<T>;
|
|
107
68
|
|
|
108
|
-
/**
|
|
109
|
-
* Remove the first value for which the provided predicate function
|
|
110
|
-
* returns `true` from the array.
|
|
111
|
-
*
|
|
112
|
-
* Returns an {@link Option} containing the removed value, or {@link None} if
|
|
113
|
-
* no matches were found.
|
|
114
|
-
*/
|
|
69
|
+
/** {@inheritDoc array.removeFn} */
|
|
115
70
|
removeFn(predicate: (value: T, index: number, obj: Array<T>) => boolean): Option<T>;
|
|
116
71
|
|
|
117
|
-
/**
|
|
118
|
-
* Remove the value at the given index from the array.
|
|
119
|
-
*
|
|
120
|
-
* Returns an {@link Option} containing the removed value, or {@link None} if
|
|
121
|
-
* the index was out of bounds.
|
|
122
|
-
*/
|
|
72
|
+
/** {@inheritDoc array.removeIndex} */
|
|
123
73
|
removeIndex(index: number): Option<T>;
|
|
124
74
|
|
|
125
|
-
/**
|
|
126
|
-
* Return a copy of the array with any `undefined` values removed.
|
|
127
|
-
*/
|
|
75
|
+
/** {@inheritDoc array.present} */
|
|
128
76
|
present(): Array<Present<T>>;
|
|
129
77
|
|
|
130
|
-
/**
|
|
131
|
-
* Return a copy of the array with any `null` or `undefined` values removed.
|
|
132
|
-
*/
|
|
78
|
+
/** {@inheritDoc array.nonNullable} */
|
|
133
79
|
nonNullable(): Array<NonNullable<T>>;
|
|
134
80
|
|
|
135
|
-
/**
|
|
136
|
-
* Checked index operator. Returns {@link None} if an index isn't
|
|
137
|
-
* present, even for sparse arrays. Returns a {@link Some} if the index
|
|
138
|
-
* is present, even if the value is `undefined`.
|
|
139
|
-
*/
|
|
81
|
+
/** {@inheritDoc array.get} */
|
|
140
82
|
get(index: number): Option<T>;
|
|
141
83
|
|
|
142
|
-
/**
|
|
143
|
-
* Test whether a value is an array with the same contents as this one.
|
|
144
|
-
*/
|
|
84
|
+
/** {@inheritDoc array.equals} */
|
|
145
85
|
equals<U = unknown>(other: unknown, equalsFn?: (a: T, b: U) => boolean): other is Array<T>;
|
|
146
86
|
}
|
|
147
87
|
|
|
@@ -149,22 +89,13 @@ declare global {
|
|
|
149
89
|
* Added methods on the {@link Iterator} global object.
|
|
150
90
|
*/
|
|
151
91
|
interface IteratorConstructor {
|
|
152
|
-
/**
|
|
153
|
-
* Construct an empty iterator.
|
|
154
|
-
*/
|
|
92
|
+
/** {@inheritDoc iterator.empty} */
|
|
155
93
|
empty<T>(): IteratorObject<T>;
|
|
156
|
-
/**
|
|
157
|
-
* Sequence multiple iterators into a single one.
|
|
158
|
-
* @see https://github.com/tc39/proposal-iterator-sequencing
|
|
159
|
-
*/
|
|
94
|
+
/** {@inheritDoc iterator.concat} */
|
|
160
95
|
concat<T>(...inputs: Array<Iterable<T>>): IteratorObject<T>;
|
|
161
|
-
/**
|
|
162
|
-
* @see https://github.com/tc39/proposal-joint-iteration
|
|
163
|
-
*/
|
|
96
|
+
/** {@inheritDoc iterator.zip} */
|
|
164
97
|
zip<T>(inputs: Iterable<Iterable<T>>): IteratorObject<Array<T>>;
|
|
165
|
-
/**
|
|
166
|
-
* @see https://github.com/tc39/proposal-joint-iteration
|
|
167
|
-
*/
|
|
98
|
+
/** {@inheritDoc iterator.zipKeyed} */
|
|
168
99
|
zipKeyed<T>(inputs: Record<string, Iterable<T>>): IteratorObject<Record<string, T>>;
|
|
169
100
|
}
|
|
170
101
|
|
|
@@ -173,61 +104,32 @@ declare global {
|
|
|
173
104
|
*/
|
|
174
105
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
175
106
|
interface IteratorObject<T, TReturn, TNext> {
|
|
176
|
-
/**
|
|
177
|
-
* Get the next value from the iterator, wrapped in an {@link Option}
|
|
178
|
-
* type. If the iterator has no more values, return {@link None}.
|
|
179
|
-
*/
|
|
107
|
+
/** {@inheritDoc iterator.takeOne} */
|
|
180
108
|
takeOne(): Option<T>;
|
|
181
|
-
/**
|
|
182
|
-
* Take items from the iterator only until the first time `predicate` returns false.
|
|
183
|
-
*/
|
|
109
|
+
/** {@inheritDoc iterator.takeWhile} */
|
|
184
110
|
takeWhile<S extends T>(
|
|
185
|
-
predicate: (value: T, index: number) => value is S
|
|
111
|
+
predicate: (value: T, index: number) => value is S,
|
|
186
112
|
): IteratorObject<S, undefined>;
|
|
187
113
|
/** @ignore */
|
|
188
114
|
takeWhile(predicate: (value: T, index: number) => boolean): IteratorObject<T, undefined>;
|
|
189
|
-
/**
|
|
190
|
-
* Ignore all items matching `predicate` until the first item that
|
|
191
|
-
* doesn't match.
|
|
192
|
-
*/
|
|
115
|
+
/** {@inheritDoc iterator.skipWhile} */
|
|
193
116
|
skipWhile(predicate: (value: T, index: number) => boolean): IteratorObject<T, undefined>;
|
|
194
|
-
/**
|
|
195
|
-
* Iterate until calling `mapFn` on an item returns a value, then return
|
|
196
|
-
* that value. Return `undefined` if `mapFn` never returns a value.
|
|
197
|
-
*/
|
|
117
|
+
/** {@inheritDoc iterator.findMap} */
|
|
198
118
|
findMap<U>(mapFn: (value: T) => NonNullable<U> | undefined): NonNullable<U> | undefined;
|
|
199
|
-
/**
|
|
200
|
-
|
|
201
|
-
|
|
119
|
+
/** {@inheritDoc iterator.chunks} */
|
|
120
|
+
chunks(size: number): IteratorObject<Array<T>, undefined>;
|
|
121
|
+
/** {@inheritDoc iterator.partition} */
|
|
202
122
|
partition(size: number): IteratorObject<Array<T>, undefined>;
|
|
203
|
-
/**
|
|
204
|
-
* As {@link IteratorObject#partition}, but if the input length isn't
|
|
205
|
-
* divisible by `size`, ensure the *first* array is the shortest one
|
|
206
|
-
* rather than the last.
|
|
207
|
-
*
|
|
208
|
-
* Be warned that this requires the entire input iterable to be read up
|
|
209
|
-
* front to decide its length, so this function is not lazy.
|
|
210
|
-
*/
|
|
123
|
+
/** {@inheritDoc iterator.frontBiasedPartition} */
|
|
211
124
|
frontBiasedPartition(size: number): Array<Array<T>>;
|
|
212
|
-
/**
|
|
213
|
-
* Filter out any items which are `undefined`.
|
|
214
|
-
*/
|
|
125
|
+
/** {@inheritDoc iterator.present} */
|
|
215
126
|
present(): IteratorObject<Present<T>, undefined>;
|
|
216
|
-
/**
|
|
217
|
-
* Filter out any items which are `null` or `undefined`.
|
|
218
|
-
*/
|
|
127
|
+
/** {@inheritDoc iterator.nonNullable} */
|
|
219
128
|
nonNullable(): IteratorObject<NonNullable<T>, undefined>;
|
|
220
|
-
/**
|
|
221
|
-
* Test whether the given Iterable has the same contents as this
|
|
222
|
-
* iterator.
|
|
223
|
-
*
|
|
224
|
-
* Note that this will consume this iterator up to the point
|
|
225
|
-
* where the values diverge. You should not rely on any particular state
|
|
226
|
-
* of the iterator afterwards, but consider it spent.
|
|
227
|
-
*/
|
|
129
|
+
/** {@inheritDoc iterator.equals} */
|
|
228
130
|
equals<T = unknown, U = unknown>(
|
|
229
131
|
value: Iterable<U>,
|
|
230
|
-
equalsFn?: (a: T, b: U) => boolean
|
|
132
|
+
equalsFn?: (a: T, b: U) => boolean,
|
|
231
133
|
): boolean;
|
|
232
134
|
}
|
|
233
135
|
}
|
|
@@ -235,133 +137,38 @@ declare global {
|
|
|
235
137
|
// Object
|
|
236
138
|
|
|
237
139
|
defineProperties(Object, {
|
|
238
|
-
get
|
|
239
|
-
|
|
240
|
-
},
|
|
241
|
-
|
|
242
|
-
mapEntries<A, B>(
|
|
243
|
-
obj: Record<string, A>,
|
|
244
|
-
fn: (entry: [key: string, value: A]) => [string, B]
|
|
245
|
-
): Record<string, B> {
|
|
246
|
-
return Object.fromEntries(Object.entries(obj).map(fn));
|
|
247
|
-
},
|
|
140
|
+
get: object.get,
|
|
141
|
+
mapEntries: object.mapEntries,
|
|
248
142
|
});
|
|
249
143
|
|
|
250
144
|
// Map
|
|
251
145
|
|
|
252
146
|
defineProperties(Map.prototype, {
|
|
253
|
-
getOrInsertComputed
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
defaultValue: (key: K) => NonNullable<V>
|
|
257
|
-
): V {
|
|
258
|
-
const result = this.get(key);
|
|
259
|
-
if (result !== undefined) {
|
|
260
|
-
return result;
|
|
261
|
-
}
|
|
262
|
-
const newValue = defaultValue(key);
|
|
263
|
-
this.set(key, newValue);
|
|
264
|
-
return newValue;
|
|
265
|
-
},
|
|
266
|
-
remove<K, V>(this: Map<K, V>, key: K): Option<V> {
|
|
267
|
-
const result = this.get(key);
|
|
268
|
-
return this.delete(key) ? Some(result!) : None;
|
|
269
|
-
},
|
|
147
|
+
getOrInsertComputed: map.getOrInsertComputed,
|
|
148
|
+
getOrSet: map.getOrSet,
|
|
149
|
+
remove: map.remove,
|
|
270
150
|
});
|
|
271
151
|
|
|
272
152
|
// WeakMap
|
|
273
153
|
|
|
274
154
|
defineProperties(WeakMap.prototype, {
|
|
275
|
-
getOrInsertComputed
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
defaultValue: (key: K) => NonNullable<V>
|
|
279
|
-
): V {
|
|
280
|
-
const result = this.get(key);
|
|
281
|
-
if (result !== undefined) {
|
|
282
|
-
return result;
|
|
283
|
-
}
|
|
284
|
-
const newValue = defaultValue(key);
|
|
285
|
-
this.set(key, newValue);
|
|
286
|
-
return newValue;
|
|
287
|
-
},
|
|
288
|
-
remove<K extends WeakKey, V>(this: WeakMap<K, V>, key: K): Option<V> {
|
|
289
|
-
const result = this.get(key);
|
|
290
|
-
return this.delete(key) ? Some(result!) : None;
|
|
291
|
-
},
|
|
155
|
+
getOrInsertComputed: weakmap.getOrInsertComputed,
|
|
156
|
+
getOrSet: weakmap.getOrSet,
|
|
157
|
+
remove: weakmap.remove,
|
|
292
158
|
});
|
|
293
159
|
|
|
294
160
|
// Array
|
|
295
161
|
|
|
296
162
|
defineProperties(Array.prototype, {
|
|
297
|
-
remove
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
},
|
|
307
|
-
|
|
308
|
-
removeIndex<T>(this: Array<T>, index: number): Option<T> {
|
|
309
|
-
if (!Number.isInteger(index)) {
|
|
310
|
-
throw new TypeError(`Array.removeIndex(): index ${index} is not an integer`);
|
|
311
|
-
}
|
|
312
|
-
if (index < 0 || index >= this.length) {
|
|
313
|
-
return None;
|
|
314
|
-
}
|
|
315
|
-
const removed = this.splice(index, 1).pop();
|
|
316
|
-
return Option.from(removed);
|
|
317
|
-
},
|
|
318
|
-
|
|
319
|
-
insert<T>(this: Array<T>, value: T, index: number): Array<T> {
|
|
320
|
-
if (!Number.isInteger(index)) {
|
|
321
|
-
throw new TypeError(`Array.insert(): index ${index} is not an integer`);
|
|
322
|
-
}
|
|
323
|
-
if (index > this.length || index < 0) {
|
|
324
|
-
throw new RangeError(`Array.insert: index ${index} out of bounds`);
|
|
325
|
-
}
|
|
326
|
-
this.splice(index, 0, value);
|
|
327
|
-
return this;
|
|
328
|
-
},
|
|
329
|
-
|
|
330
|
-
insertOrdered<T>(
|
|
331
|
-
this: Array<T>,
|
|
332
|
-
value: T,
|
|
333
|
-
cmp: OrderFn<T>,
|
|
334
|
-
duplicates: "low" | "high" = "high"
|
|
335
|
-
): Array<T> {
|
|
336
|
-
return this.insert(
|
|
337
|
-
value,
|
|
338
|
-
(duplicates === "low" ? bisectLow : bisectHigh)(cmp, this, value)
|
|
339
|
-
);
|
|
340
|
-
},
|
|
341
|
-
|
|
342
|
-
present<T>(this: Array<T>): Array<Present<T>> {
|
|
343
|
-
return this.filter((value: T): value is Present<T> => value !== undefined);
|
|
344
|
-
},
|
|
345
|
-
|
|
346
|
-
nonNullable<T>(this: Array<T>): Array<NonNullable<T>> {
|
|
347
|
-
return this.filter((value: T): value is NonNullable<T> => value !== undefined);
|
|
348
|
-
},
|
|
349
|
-
|
|
350
|
-
get<T>(this: Array<T>, index: number): Option<T> {
|
|
351
|
-
return Object.get(this, index);
|
|
352
|
-
},
|
|
353
|
-
|
|
354
|
-
equals<T, U = unknown>(
|
|
355
|
-
this: Array<T>,
|
|
356
|
-
other: unknown,
|
|
357
|
-
equalsFn?: (a: T, b: U) => boolean
|
|
358
|
-
): other is Array<T> {
|
|
359
|
-
return (
|
|
360
|
-
Array.isArray(other) &&
|
|
361
|
-
this.length === other.length &&
|
|
362
|
-
Iterator.from(this).equals(other, equalsFn)
|
|
363
|
-
);
|
|
364
|
-
},
|
|
163
|
+
remove: array.remove,
|
|
164
|
+
removeFn: array.removeFn,
|
|
165
|
+
removeIndex: array.removeIndex,
|
|
166
|
+
insert: array.insert,
|
|
167
|
+
insertOrdered: array.insertOrdered,
|
|
168
|
+
present: array.present,
|
|
169
|
+
nonNullable: array.nonNullable,
|
|
170
|
+
get: array.get,
|
|
171
|
+
equals: array.equals,
|
|
365
172
|
});
|
|
366
173
|
|
|
367
174
|
shimUnscopables("remove");
|
|
@@ -377,158 +184,22 @@ shimUnscopables("equals");
|
|
|
377
184
|
// Iterator
|
|
378
185
|
|
|
379
186
|
defineProperties(Iterator, {
|
|
380
|
-
empty
|
|
381
|
-
|
|
382
|
-
|
|
187
|
+
empty: iterator.empty,
|
|
188
|
+
concat: iterator.concat,
|
|
189
|
+
zip: iterator.zip,
|
|
190
|
+
zipKeyed: iterator.zipKeyed,
|
|
383
191
|
});
|
|
384
192
|
|
|
385
193
|
defineProperties(Iterator.prototype, {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
let done = false;
|
|
398
|
-
return Iterator.from<T>({
|
|
399
|
-
next(): IteratorResult<T, undefined> {
|
|
400
|
-
if (!done) {
|
|
401
|
-
const result = iter.next();
|
|
402
|
-
if (result.done === true) {
|
|
403
|
-
return result;
|
|
404
|
-
}
|
|
405
|
-
if (predicate(result.value, index++)) {
|
|
406
|
-
return result;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
done = true;
|
|
410
|
-
return { done: true, value: undefined };
|
|
411
|
-
},
|
|
412
|
-
});
|
|
413
|
-
},
|
|
414
|
-
|
|
415
|
-
skipWhile<T>(
|
|
416
|
-
this: IteratorObject<T, undefined>,
|
|
417
|
-
predicate: (value: T, index: number) => boolean
|
|
418
|
-
): IteratorObject<T, undefined> {
|
|
419
|
-
const iter = this;
|
|
420
|
-
let index = 0;
|
|
421
|
-
let skipped = false;
|
|
422
|
-
return Iterator.from<T>({
|
|
423
|
-
next(): IteratorResult<T, undefined> {
|
|
424
|
-
if (skipped) {
|
|
425
|
-
return iter.next();
|
|
426
|
-
}
|
|
427
|
-
while (true) {
|
|
428
|
-
const result = iter.next();
|
|
429
|
-
if (result.done === true) {
|
|
430
|
-
return result;
|
|
431
|
-
}
|
|
432
|
-
if (!predicate(result.value, index++)) {
|
|
433
|
-
skipped = true;
|
|
434
|
-
return result;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
},
|
|
438
|
-
});
|
|
439
|
-
},
|
|
440
|
-
|
|
441
|
-
findMap<T, U>(
|
|
442
|
-
this: IteratorObject<T, undefined>,
|
|
443
|
-
mapFn: (value: T, index: number) => NonNullable<U> | undefined
|
|
444
|
-
): NonNullable<U> | undefined {
|
|
445
|
-
let index = 0;
|
|
446
|
-
while (true) {
|
|
447
|
-
const result = this.next();
|
|
448
|
-
if (result.done === true) {
|
|
449
|
-
return undefined;
|
|
450
|
-
}
|
|
451
|
-
const mapped = mapFn(result.value, index++);
|
|
452
|
-
if (mapped !== undefined) {
|
|
453
|
-
return mapped;
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
},
|
|
457
|
-
|
|
458
|
-
partition<T>(
|
|
459
|
-
this: IteratorObject<T, undefined>,
|
|
460
|
-
size: number
|
|
461
|
-
): IteratorObject<Array<T>, undefined> {
|
|
462
|
-
const iter = this;
|
|
463
|
-
let done = false;
|
|
464
|
-
return Iterator.from<Array<T>>({
|
|
465
|
-
next(): IteratorResult<Array<T>, undefined> {
|
|
466
|
-
if (done) {
|
|
467
|
-
return { done: true, value: undefined };
|
|
468
|
-
}
|
|
469
|
-
const part = [];
|
|
470
|
-
while (true) {
|
|
471
|
-
const result = iter.next();
|
|
472
|
-
if (result.done === true) {
|
|
473
|
-
done = true;
|
|
474
|
-
return part.length > 0
|
|
475
|
-
? { done: false, value: part }
|
|
476
|
-
: { done: true, value: undefined };
|
|
477
|
-
}
|
|
478
|
-
part.push(result.value);
|
|
479
|
-
if (part.length === size) {
|
|
480
|
-
return { done: false, value: part };
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
},
|
|
484
|
-
});
|
|
485
|
-
},
|
|
486
|
-
|
|
487
|
-
frontBiasedPartition<T>(this: IteratorObject<T, undefined>, size: number): Array<Array<T>> {
|
|
488
|
-
const input = this.toArray();
|
|
489
|
-
let inputPos = 0;
|
|
490
|
-
const firstLength = input.length % size;
|
|
491
|
-
const output: Array<Array<T>> = [];
|
|
492
|
-
if (firstLength > 0) {
|
|
493
|
-
output.push(input.slice(0, firstLength));
|
|
494
|
-
inputPos = firstLength;
|
|
495
|
-
}
|
|
496
|
-
while (inputPos < input.length) {
|
|
497
|
-
output.push(input.slice(inputPos, inputPos + size));
|
|
498
|
-
inputPos += size;
|
|
499
|
-
}
|
|
500
|
-
assert(inputPos === input.length);
|
|
501
|
-
return output;
|
|
502
|
-
},
|
|
503
|
-
|
|
504
|
-
present<T>(this: IteratorObject<T, undefined>): IteratorObject<Present<T>, undefined> {
|
|
505
|
-
return Iterator.from(this.filter((item): item is Present<T> => item !== undefined));
|
|
506
|
-
},
|
|
507
|
-
|
|
508
|
-
nonNullable<T>(this: IteratorObject<T, undefined>): IteratorObject<NonNullable<T>, undefined> {
|
|
509
|
-
return Iterator.from(
|
|
510
|
-
this.filter((item): item is NonNullable<T> => item !== undefined && item !== null)
|
|
511
|
-
);
|
|
512
|
-
},
|
|
513
|
-
|
|
514
|
-
equals(
|
|
515
|
-
this: IteratorObject<unknown, undefined>,
|
|
516
|
-
value: Iterable<unknown>,
|
|
517
|
-
equalsFn: (a: unknown, b: unknown) => boolean = Object.is
|
|
518
|
-
): boolean {
|
|
519
|
-
const other = Iterator.from(value);
|
|
520
|
-
while (true) {
|
|
521
|
-
const a = this.next();
|
|
522
|
-
const b = other.next();
|
|
523
|
-
if (
|
|
524
|
-
a.done !== b.done ||
|
|
525
|
-
(a.done === false && b.done === false && !equalsFn(a.value, b.value as any))
|
|
526
|
-
) {
|
|
527
|
-
return false;
|
|
528
|
-
}
|
|
529
|
-
if (a.done === true && b.done === true) {
|
|
530
|
-
return true;
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
},
|
|
194
|
+
chunks: iterator.chunks,
|
|
195
|
+
takeOne: iterator.takeOne,
|
|
196
|
+
takeWhile: iterator.takeWhile,
|
|
197
|
+
skipWhile: iterator.skipWhile,
|
|
198
|
+
findMap: iterator.findMap,
|
|
199
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
200
|
+
partition: iterator.partition,
|
|
201
|
+
frontBiasedPartition: iterator.frontBiasedPartition,
|
|
202
|
+
present: iterator.present,
|
|
203
|
+
nonNullable: iterator.nonNullable,
|
|
204
|
+
equals: iterator.equals,
|
|
534
205
|
});
|