extra-iterator 0.4.1 → 0.6.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 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 an iterator that yields arrays containing the values that exist in the same indexes in each of the
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, starting from
30
- * `start` (default 0) and ending at `end`. (exclusive)
29
+ * Creates an iterator that yields incrementing numbers.
31
30
  *
32
- * If `end` is omitted, counts to Infinity.
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(): ExtraIterator<number>;
37
- static count(end: number): ExtraIterator<number>;
38
- static count(start: number, end: number): ExtraIterator<number>;
39
- static count(start: number, end: number, interval: number): ExtraIterator<number>;
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 `count` times.
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>(count: number, value: T): ExtraIterator<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>;
@@ -200,6 +212,18 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
200
212
  * // returns [1, 'a', 2, 'a', 3, 'a', 4]
201
213
  */
202
214
  interpose<U>(separator: U): ExtraIterator<T | U>;
215
+ /**
216
+ * Creates a new iterator that yields the values of this iterator interposed by separator values produced by calling
217
+ * the callback function provided as argument.
218
+ *
219
+ * @example
220
+ *
221
+ * ExtraIterator.from([2, 3, 5, 8])
222
+ * .interposeWith((lhs, rhs) => (lhs + rhs) / 2)
223
+ * .toArray()
224
+ * // returns [2, 2.5, 3, 4, 5, 6.5, 8]
225
+ */
226
+ interposeWith<U>(separatorProvider: (lhs: T, rhs: T, index: number) => U): ExtraIterator<T | U>;
203
227
  /**
204
228
  * Creates a new iterator that yields the values of this iterator and the values of the provided iterator
205
229
  * interleaved (alternating). The elements of this iterator always come before the elements of the other iterator.
@@ -231,6 +255,14 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
231
255
  * Returns an iterator the provided element if this iterator is empty; otherwise, it returns this iterator.
232
256
  */
233
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>;
234
266
  /**
235
267
  * Returns the first element of the iterator, or `undefined` if the iterator is empty.
236
268
  */
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
- static count(...args) {
33
- const [start, end, interval] = args.length === 0 ? [0, Infinity, 1]
34
- : args.length === 1 ? [0, args[0], 1]
35
- : [args[0], args[1], args[2] ?? 1];
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
- for (let counter = start; counter < end; counter += interval) {
38
- yield counter;
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 `count` times.
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(count, value) {
54
+ static repeat(value) {
48
55
  return new ExtraIterator(function* () {
49
- for (let index = 0; index < count; index++) {
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
  // =================================================================================================================
@@ -330,6 +353,28 @@ export class ExtraIterator extends Iterator {
330
353
  }
331
354
  }.call(this));
332
355
  }
356
+ /**
357
+ * Creates a new iterator that yields the values of this iterator interposed by separator values produced by calling
358
+ * the callback function provided as argument.
359
+ *
360
+ * @example
361
+ *
362
+ * ExtraIterator.from([2, 3, 5, 8])
363
+ * .interposeWith((lhs, rhs) => (lhs + rhs) / 2)
364
+ * .toArray()
365
+ * // returns [2, 2.5, 3, 4, 5, 6.5, 8]
366
+ */
367
+ interposeWith(separatorProvider) {
368
+ return ExtraIterator.from(function* () {
369
+ for (let previous = this.next(), next, index = 0; !previous.done; previous = next, index++) {
370
+ yield previous.value;
371
+ next = this.next();
372
+ if (!next.done) {
373
+ yield separatorProvider(previous.value, next.value, index);
374
+ }
375
+ }
376
+ }.call(this));
377
+ }
333
378
  /**
334
379
  * Creates a new iterator that yields the values of this iterator and the values of the provided iterator
335
380
  * interleaved (alternating). The elements of this iterator always come before the elements of the other iterator.
@@ -401,6 +446,24 @@ export class ExtraIterator extends Iterator {
401
446
  }
402
447
  }.call(this));
403
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
+ }
404
467
  // =================================================================================================================
405
468
  // AGGREGATING FUNCTIONS
406
469
  // -----------------------------------------------------------------------------------------------------------------
@@ -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(3, 'x');
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]);
@@ -57,6 +66,10 @@ describe('ExtraIterator', () => {
57
66
  const iterator = ExtraIterator.from([1, 2, 3]).interpose(0);
58
67
  expect(iterator.toArray()).toEqual([1, 0, 2, 0, 3]);
59
68
  });
69
+ it('should interpose with a function', () => {
70
+ const iterator = ExtraIterator.from([1, 2, 3, 5, 8, 13]).interposeWith((a, b) => (a + b) / 2);
71
+ expect(iterator.toArray()).toEqual([1, 1.5, 2, 2.5, 3, 4, 5, 6.5, 8, 10.5, 13]);
72
+ });
60
73
  it('should chunk values into groups of a given size', () => {
61
74
  const iterator = ExtraIterator.from([1, 2, 3, 4]).chunk(2);
62
75
  expect(iterator.toArray()).toEqual([[1, 2], [3, 4]]);
@@ -137,4 +150,8 @@ describe('ExtraIterator', () => {
137
150
  const chain = handlers.toChainOfResponsibilityFunction(next => next());
138
151
  expect(() => chain()).toThrow();
139
152
  });
153
+ it('should repeat values', () => {
154
+ const iterator = ExtraIterator.from([1, 2, 3]).loop(3);
155
+ expect(iterator.toArray()).toEqual([1, 2, 3, 1, 2, 3, 1, 2, 3]);
156
+ });
140
157
  });
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.4.1",
6
+ "version": "0.6.0",
7
7
  "type": "module",
8
8
  "exports": {
9
9
  ".": "./dist/index.js",