extra-iterator 0.5.0 → 0.7.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/dist/index.d.ts +51 -13
- package/dist/index.js +86 -21
- package/dist/index.test.js +34 -2
- package/package.json +1 -1
- package/dist/chain-of-responsibility.d.ts +0 -0
- package/dist/chain-of-responsibility.js +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
|
|
|
13
13
|
static zip<A, B, C, D, E, F, G>(a: ExtraIteratorSource<A>, b: ExtraIteratorSource<B>, c: ExtraIteratorSource<C>, d: ExtraIteratorSource<D>, e: ExtraIteratorSource<E>, f: ExtraIteratorSource<F>, g: ExtraIteratorSource<G>): ExtraIterator<[A, B, C, D, E, F, G]>;
|
|
14
14
|
static zip<A, B, C, D, E, F, G, H>(a: ExtraIteratorSource<A>, b: ExtraIteratorSource<B>, c: ExtraIteratorSource<C>, d: ExtraIteratorSource<D>, e: ExtraIteratorSource<E>, f: ExtraIteratorSource<F>, g: ExtraIteratorSource<G>, h: ExtraIteratorSource<H>): ExtraIterator<[A, B, C, D, E, F, G, H]>;
|
|
15
15
|
/**
|
|
16
|
-
* Creates
|
|
17
|
-
* provided iterators.
|
|
16
|
+
* Creates a new iterator that iterates over all the provided iterators simultaneously. The returned iterator yields
|
|
17
|
+
* arrays containing the values yielded by each of the provided iterators.
|
|
18
18
|
*
|
|
19
19
|
* @example ExtraIterator.zip([1, 2, 3], ['a', 'b', 'c']).toArray() // returns [ [1, 'a'], [2, 'b'], [3, 'c'] ]
|
|
20
20
|
*/
|
|
@@ -26,23 +26,35 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
|
|
|
26
26
|
*/
|
|
27
27
|
static empty<T = any>(): ExtraIterator<T>;
|
|
28
28
|
/**
|
|
29
|
-
* Creates an iterator that yields incrementing numbers
|
|
30
|
-
* `start` (default 0) and ending at `end`. (exclusive)
|
|
29
|
+
* Creates an iterator that yields incrementing numbers.
|
|
31
30
|
*
|
|
32
|
-
*
|
|
31
|
+
* > ⚠ This iterator is infinite. Use {@link take} method if you want a specific number of values.
|
|
33
32
|
*
|
|
34
|
-
* @example ExtraIterator.count(5).toArray() // returns [0, 1, 2, 3, 4]
|
|
33
|
+
* @example ExtraIterator.count().take(5).toArray() // returns [0, 1, 2, 3, 4]
|
|
35
34
|
*/
|
|
36
|
-
static count(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
static count({ start, interval }?: {
|
|
36
|
+
start?: number | undefined;
|
|
37
|
+
interval?: number | undefined;
|
|
38
|
+
}): ExtraIterator<number>;
|
|
40
39
|
/**
|
|
41
|
-
* Creates an iterator that yields the provided value
|
|
40
|
+
* Creates an iterator that repeatedly yields the provided value.
|
|
41
|
+
*
|
|
42
|
+
* > ⚠ This iterator is infinite. Use {@link take} method if you want a specific number of values.
|
|
42
43
|
*
|
|
43
44
|
* @example ExtraIterator.repeat(3, 'a').toArray() // returns ['a', 'a', 'a']
|
|
44
45
|
*/
|
|
45
|
-
static repeat<T>(
|
|
46
|
+
static repeat<T>(value: T): ExtraIterator<T>;
|
|
47
|
+
/**
|
|
48
|
+
* Generates random cryptographically strong random numbers.
|
|
49
|
+
*
|
|
50
|
+
* > ⚠ This iterator is infinite. Use {@link take} method if you want a specific number of values.
|
|
51
|
+
*
|
|
52
|
+
* @param param0
|
|
53
|
+
* @returns
|
|
54
|
+
*/
|
|
55
|
+
static random({ bufferSize }?: {
|
|
56
|
+
bufferSize?: number | undefined;
|
|
57
|
+
}): ExtraIterator<number>;
|
|
46
58
|
private constructor();
|
|
47
59
|
private source;
|
|
48
60
|
next(value?: any): IteratorResult<T, any>;
|
|
@@ -243,6 +255,14 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
|
|
|
243
255
|
* Returns an iterator the provided element if this iterator is empty; otherwise, it returns this iterator.
|
|
244
256
|
*/
|
|
245
257
|
defaultIfEmpty(provider: () => T): ExtraIterator<T>;
|
|
258
|
+
/**
|
|
259
|
+
* Creates a new iterator that yields the values of this iterator and then reiterates over the same values and
|
|
260
|
+
* yields each of them again, a number of times determined by the {@param times} parameter. If omitted, loops
|
|
261
|
+
* infinitely.
|
|
262
|
+
*
|
|
263
|
+
* @example ExtraIterator.from([1, 2, 3]).loop(3).toArray() // returns [1, 2, 3, 1, 2, 3, 1, 2, 3]
|
|
264
|
+
*/
|
|
265
|
+
loop(times?: number): ExtraIterator<T>;
|
|
246
266
|
/**
|
|
247
267
|
* Returns the first element of the iterator, or `undefined` if the iterator is empty.
|
|
248
268
|
*/
|
|
@@ -263,6 +283,9 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
|
|
|
263
283
|
* The returned object is composed of keys generated by calling the provided callback function on each element of
|
|
264
284
|
* this iterator, and the value for each key is an array containing all the elements that were assigned to that key.
|
|
265
285
|
*
|
|
286
|
+
* This method is similar to {@link toMap}, but the returned object is a plain, null-prototype, object, instead of a
|
|
287
|
+
* `Map`.
|
|
288
|
+
*
|
|
266
289
|
* @example
|
|
267
290
|
*
|
|
268
291
|
* ExtraIterator.from([1, 2, 3, 4, 5])
|
|
@@ -271,6 +294,20 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
|
|
|
271
294
|
* // returns { even: [2, 4], odd: [1, 3, 5] }
|
|
272
295
|
*/
|
|
273
296
|
groupBy<K extends string | symbol>(callbackfn: (value: T, index: number) => K): Record<K, T[]>;
|
|
297
|
+
/**
|
|
298
|
+
* Groups elements into separate arrays and returns a Map containing each group.
|
|
299
|
+
*
|
|
300
|
+
* The returned Map is composed of keys generated by calling the provided callback function on each element of this
|
|
301
|
+
* iterator, and the value for each key is an array containing all the elements to which the callback function
|
|
302
|
+
* returned that key.
|
|
303
|
+
*
|
|
304
|
+
* This method is similart to {@link groupBy}, but the returned object is a Map instead of a plain object.
|
|
305
|
+
*/
|
|
306
|
+
toMap<K extends string | symbol>(callbackfn: (value: T, index: number) => K): Map<K, T[]>;
|
|
307
|
+
/**
|
|
308
|
+
* Creates a set containing all the values yielded by this iterator.
|
|
309
|
+
*/
|
|
310
|
+
toSet(): Set<T>;
|
|
274
311
|
toChainOfResponsibilityFunction<ResultType = void | Promise<void>, ParamsType extends any[] = []>(invokeHandler: (handler: T, next: (...args: ParamsType) => ResultType, ...args: ParamsType) => ResultType): (...args: ParamsType) => ResultType;
|
|
275
312
|
/**
|
|
276
313
|
* Consumes the iterator and returns a value determined by calling the provided function using the iterator as
|
|
@@ -284,9 +321,10 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
|
|
|
284
321
|
* // returns { _a: 2, _b: 4 }
|
|
285
322
|
*/
|
|
286
323
|
collect<U>(collectfn: ((iter: Iterable<T>) => U)): U;
|
|
287
|
-
toSortedBy(...keys: (keyof T)[]): T[];
|
|
288
324
|
/**
|
|
289
325
|
* Consumes the iterator and returns the number of elements it contained.
|
|
326
|
+
*
|
|
327
|
+
* @example ExtraIterator.from([1, 2, 3, 4]).count() // returns 4
|
|
290
328
|
*/
|
|
291
329
|
count(): number;
|
|
292
330
|
/**
|
package/dist/index.js
CHANGED
|
@@ -29,28 +29,51 @@ export class ExtraIterator extends Iterator {
|
|
|
29
29
|
static empty() {
|
|
30
30
|
return new ExtraIterator([]);
|
|
31
31
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Creates an iterator that yields incrementing numbers.
|
|
34
|
+
*
|
|
35
|
+
* > ⚠ This iterator is infinite. Use {@link take} method if you want a specific number of values.
|
|
36
|
+
*
|
|
37
|
+
* @example ExtraIterator.count().take(5).toArray() // returns [0, 1, 2, 3, 4]
|
|
38
|
+
*/
|
|
39
|
+
static count({ start = 0, interval = 1 } = {}) {
|
|
36
40
|
return new ExtraIterator(function* () {
|
|
37
|
-
|
|
38
|
-
yield
|
|
41
|
+
while (true) {
|
|
42
|
+
yield start;
|
|
43
|
+
start += interval;
|
|
39
44
|
}
|
|
40
45
|
}());
|
|
41
46
|
}
|
|
42
47
|
/**
|
|
43
|
-
* Creates an iterator that yields the provided value
|
|
48
|
+
* Creates an iterator that repeatedly yields the provided value.
|
|
49
|
+
*
|
|
50
|
+
* > ⚠ This iterator is infinite. Use {@link take} method if you want a specific number of values.
|
|
44
51
|
*
|
|
45
52
|
* @example ExtraIterator.repeat(3, 'a').toArray() // returns ['a', 'a', 'a']
|
|
46
53
|
*/
|
|
47
|
-
static repeat(
|
|
54
|
+
static repeat(value) {
|
|
48
55
|
return new ExtraIterator(function* () {
|
|
49
|
-
|
|
56
|
+
while (true) {
|
|
50
57
|
yield value;
|
|
51
58
|
}
|
|
52
59
|
}());
|
|
53
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Generates random cryptographically strong random numbers.
|
|
63
|
+
*
|
|
64
|
+
* > ⚠ This iterator is infinite. Use {@link take} method if you want a specific number of values.
|
|
65
|
+
*
|
|
66
|
+
* @param param0
|
|
67
|
+
* @returns
|
|
68
|
+
*/
|
|
69
|
+
static random({ bufferSize = 1024 } = {}) {
|
|
70
|
+
const buffer = new Uint8Array(bufferSize);
|
|
71
|
+
return new ExtraIterator(function* () {
|
|
72
|
+
globalThis.crypto.getRandomValues(buffer);
|
|
73
|
+
yield* new Float64Array(buffer);
|
|
74
|
+
}())
|
|
75
|
+
.loop();
|
|
76
|
+
}
|
|
54
77
|
// =================================================================================================================
|
|
55
78
|
// PRIVATES
|
|
56
79
|
// =================================================================================================================
|
|
@@ -423,6 +446,24 @@ export class ExtraIterator extends Iterator {
|
|
|
423
446
|
}
|
|
424
447
|
}.call(this));
|
|
425
448
|
}
|
|
449
|
+
/**
|
|
450
|
+
* Creates a new iterator that yields the values of this iterator and then reiterates over the same values and
|
|
451
|
+
* yields each of them again, a number of times determined by the {@param times} parameter. If omitted, loops
|
|
452
|
+
* infinitely.
|
|
453
|
+
*
|
|
454
|
+
* @example ExtraIterator.from([1, 2, 3]).loop(3).toArray() // returns [1, 2, 3, 1, 2, 3, 1, 2, 3]
|
|
455
|
+
*/
|
|
456
|
+
loop(times = Infinity) {
|
|
457
|
+
return ExtraIterator.from(function* () {
|
|
458
|
+
const values = this.toArray();
|
|
459
|
+
if (values.length === 0) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
for (let i = 0; i < times; i++) {
|
|
463
|
+
yield* values;
|
|
464
|
+
}
|
|
465
|
+
}.call(this));
|
|
466
|
+
}
|
|
426
467
|
// =================================================================================================================
|
|
427
468
|
// AGGREGATING FUNCTIONS
|
|
428
469
|
// -----------------------------------------------------------------------------------------------------------------
|
|
@@ -463,6 +504,9 @@ export class ExtraIterator extends Iterator {
|
|
|
463
504
|
* The returned object is composed of keys generated by calling the provided callback function on each element of
|
|
464
505
|
* this iterator, and the value for each key is an array containing all the elements that were assigned to that key.
|
|
465
506
|
*
|
|
507
|
+
* This method is similar to {@link toMap}, but the returned object is a plain, null-prototype, object, instead of a
|
|
508
|
+
* `Map`.
|
|
509
|
+
*
|
|
466
510
|
* @example
|
|
467
511
|
*
|
|
468
512
|
* ExtraIterator.from([1, 2, 3, 4, 5])
|
|
@@ -481,6 +525,37 @@ export class ExtraIterator extends Iterator {
|
|
|
481
525
|
}
|
|
482
526
|
return result;
|
|
483
527
|
}
|
|
528
|
+
/**
|
|
529
|
+
* Groups elements into separate arrays and returns a Map containing each group.
|
|
530
|
+
*
|
|
531
|
+
* The returned Map is composed of keys generated by calling the provided callback function on each element of this
|
|
532
|
+
* iterator, and the value for each key is an array containing all the elements to which the callback function
|
|
533
|
+
* returned that key.
|
|
534
|
+
*
|
|
535
|
+
* This method is similart to {@link groupBy}, but the returned object is a Map instead of a plain object.
|
|
536
|
+
*/
|
|
537
|
+
toMap(callbackfn) {
|
|
538
|
+
const result = new Map();
|
|
539
|
+
for (let index = 0, next; next = this.next(), !next.done; index++) {
|
|
540
|
+
const key = callbackfn(next.value, index);
|
|
541
|
+
const array = result.get(key);
|
|
542
|
+
if (!array) {
|
|
543
|
+
result.set(key, [next.value]);
|
|
544
|
+
}
|
|
545
|
+
else {
|
|
546
|
+
array.push(next.value);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
return result;
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Creates a set containing all the values yielded by this iterator.
|
|
553
|
+
*/
|
|
554
|
+
toSet() {
|
|
555
|
+
const result = new Set();
|
|
556
|
+
this.forEach(value => result.add(value));
|
|
557
|
+
return result;
|
|
558
|
+
}
|
|
484
559
|
toChainOfResponsibilityFunction(invokeHandler) {
|
|
485
560
|
const handlers = this.toArray();
|
|
486
561
|
return (...initialArgs) => {
|
|
@@ -510,20 +585,10 @@ export class ExtraIterator extends Iterator {
|
|
|
510
585
|
collect(collectfn) {
|
|
511
586
|
return collectfn(this);
|
|
512
587
|
}
|
|
513
|
-
toSortedBy(...keys) {
|
|
514
|
-
return this.toArray()
|
|
515
|
-
.sort((a, b) => {
|
|
516
|
-
for (const key of keys) {
|
|
517
|
-
if (a[key] < b[key])
|
|
518
|
-
return -1;
|
|
519
|
-
if (a[key] > b[key])
|
|
520
|
-
return 1;
|
|
521
|
-
}
|
|
522
|
-
return 0;
|
|
523
|
-
});
|
|
524
|
-
}
|
|
525
588
|
/**
|
|
526
589
|
* Consumes the iterator and returns the number of elements it contained.
|
|
590
|
+
*
|
|
591
|
+
* @example ExtraIterator.from([1, 2, 3, 4]).count() // returns 4
|
|
527
592
|
*/
|
|
528
593
|
count() {
|
|
529
594
|
let count = 0;
|
package/dist/index.test.js
CHANGED
|
@@ -14,13 +14,22 @@ describe('ExtraIterator', () => {
|
|
|
14
14
|
expect(zipped.toArray()).toEqual([[1, 'a'], [2, 'b'], [3, 'c']]);
|
|
15
15
|
});
|
|
16
16
|
it('should count from 0 to a given number', () => {
|
|
17
|
-
const iterator = ExtraIterator.count(5);
|
|
17
|
+
const iterator = ExtraIterator.count().take(5);
|
|
18
18
|
expect(iterator.toArray()).toEqual([0, 1, 2, 3, 4]);
|
|
19
19
|
});
|
|
20
|
+
it('should count in 2s, starting from 5', () => {
|
|
21
|
+
const iterator = ExtraIterator.count({ start: 5, interval: 2 }).take(5);
|
|
22
|
+
expect(iterator.toArray()).toEqual([5, 7, 9, 11, 13]);
|
|
23
|
+
});
|
|
20
24
|
it('should repeat a value a given number of times', () => {
|
|
21
|
-
const iterator = ExtraIterator.repeat(
|
|
25
|
+
const iterator = ExtraIterator.repeat('x').take(3);
|
|
22
26
|
expect(iterator.toArray()).toEqual(['x', 'x', 'x']);
|
|
23
27
|
});
|
|
28
|
+
it('should yield random values', () => {
|
|
29
|
+
const values = ExtraIterator.random().take(5).toArray();
|
|
30
|
+
expect(values.length).toBe(5);
|
|
31
|
+
expect(values.every(value => typeof value === 'number')).toBe(true);
|
|
32
|
+
});
|
|
24
33
|
it('should filter values based on a predicate', () => {
|
|
25
34
|
const iterator = ExtraIterator.from([1, 2, 3, 4]).filter(x => x % 2 === 0);
|
|
26
35
|
expect(iterator.toArray()).toEqual([2, 4]);
|
|
@@ -117,6 +126,25 @@ describe('ExtraIterator', () => {
|
|
|
117
126
|
b: ['banana'],
|
|
118
127
|
});
|
|
119
128
|
});
|
|
129
|
+
it('should convert to a Map', () => {
|
|
130
|
+
const iterator = ExtraIterator.from([{ key: 'a', value: 1 }, { key: 'b', value: 2 }, { key: 'a', value: 3 }]);
|
|
131
|
+
const map = iterator.toMap(item => item.key);
|
|
132
|
+
expect(map).toBeInstanceOf(Map);
|
|
133
|
+
expect(map).toEqual(new Map([
|
|
134
|
+
['a', [{ key: 'a', value: 1 }, { key: 'a', value: 3 }]],
|
|
135
|
+
['b', [{ key: 'b', value: 2 }]],
|
|
136
|
+
]));
|
|
137
|
+
});
|
|
138
|
+
it('should convert to a Set', () => {
|
|
139
|
+
const iterator = ExtraIterator.from([3, 1, 3, 2, 2, 1, 3]);
|
|
140
|
+
const set = iterator.toSet();
|
|
141
|
+
expect(set).toBeInstanceOf(Set);
|
|
142
|
+
expect(set.size).toBe(3);
|
|
143
|
+
expect(set.has(1)).toBe(true);
|
|
144
|
+
expect(set.has(2)).toBe(true);
|
|
145
|
+
expect(set.has(3)).toBe(true);
|
|
146
|
+
expect(set).toEqual(new Set([3, 1, 2]));
|
|
147
|
+
});
|
|
120
148
|
it('should collect values using a custom collector', () => {
|
|
121
149
|
const iterator = ExtraIterator.from([1, 2, 3]);
|
|
122
150
|
const sum = iterator.collect(iter => Array.from(iter).reduce((a, b) => a + b, 0));
|
|
@@ -141,4 +169,8 @@ describe('ExtraIterator', () => {
|
|
|
141
169
|
const chain = handlers.toChainOfResponsibilityFunction(next => next());
|
|
142
170
|
expect(() => chain()).toThrow();
|
|
143
171
|
});
|
|
172
|
+
it('should repeat values', () => {
|
|
173
|
+
const iterator = ExtraIterator.from([1, 2, 3]).loop(3);
|
|
174
|
+
expect(iterator.toArray()).toEqual([1, 2, 3, 1, 2, 3, 1, 2, 3]);
|
|
175
|
+
});
|
|
144
176
|
});
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "An extension of the Iterator class with additional utility helper functions.",
|
|
4
4
|
"author": "Leonardo Raele <leonardoraele@gmail.com>",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.7.0",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": "./dist/index.js",
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|