extra-iterator 0.11.0 → 0.11.1
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 +9 -8
- package/dist/index.js +11 -14
- package/dist/index.test.js +103 -10
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -163,11 +163,11 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
|
|
|
163
163
|
* @example
|
|
164
164
|
*
|
|
165
165
|
* ExtraIterator.from([4, 5, 6])
|
|
166
|
-
* .
|
|
166
|
+
* .prependAll([1, 2, 3])
|
|
167
167
|
* .toArray()
|
|
168
168
|
* // returns [1, 2, 3, 4, 5, 6]
|
|
169
169
|
*/
|
|
170
|
-
|
|
170
|
+
prependAll<U>(items: Iterable<U>): ExtraIterator<T | U>;
|
|
171
171
|
/**
|
|
172
172
|
* Creates a new iterator that invokes the provided callback function over each element of this iterator and yields
|
|
173
173
|
* the elements for which the callback returns `true`, only for as long as the callback returns `true`.
|
|
@@ -213,9 +213,9 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
|
|
|
213
213
|
/**
|
|
214
214
|
* Groups the elements in this iterator into groups of variable size.
|
|
215
215
|
*
|
|
216
|
-
* This method calls the provided predicate function for each pair of adjacent elements in this iterator.
|
|
217
|
-
* return `true` if the elements should belong to the same group, or `false` if they should belong
|
|
218
|
-
* groups.
|
|
216
|
+
* This method calls the provided predicate function for each pair of adjacent elements in this iterator. The
|
|
217
|
+
* function should return `true` if the elements should belong to the same group, or `false` if they should belong
|
|
218
|
+
* to different groups.
|
|
219
219
|
*
|
|
220
220
|
* The resulting iterator yields arrays of elements that belong to the same group.
|
|
221
221
|
*
|
|
@@ -292,7 +292,8 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
|
|
|
292
292
|
*/
|
|
293
293
|
splice(startIndex: number, deleteCount: number, ...newItems: T[]): ExtraIterator<T>;
|
|
294
294
|
/**
|
|
295
|
-
*
|
|
295
|
+
* If this iterator is empty, returns an iterator with the provided element as its only element; otherwise, it
|
|
296
|
+
* returns a copy of this iterator.
|
|
296
297
|
*/
|
|
297
298
|
defaultIfEmpty(provider: () => T): ExtraIterator<T>;
|
|
298
299
|
/**
|
|
@@ -380,8 +381,8 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
|
|
|
380
381
|
*
|
|
381
382
|
* @example
|
|
382
383
|
*
|
|
383
|
-
* ExtraIterator.from([1, 2, 3]).
|
|
384
|
-
* ExtraIterator.from([1, 2, 3, 1]).
|
|
384
|
+
* ExtraIterator.from([1, 2, 3]).testUnique() // returns true
|
|
385
|
+
* ExtraIterator.from([1, 2, 3, 1]).testUnique() // returns false
|
|
385
386
|
*/
|
|
386
387
|
testUnique(mapper?: (value: T) => unknown): boolean;
|
|
387
388
|
/**
|
package/dist/index.js
CHANGED
|
@@ -271,11 +271,11 @@ export class ExtraIterator extends Iterator {
|
|
|
271
271
|
* @example
|
|
272
272
|
*
|
|
273
273
|
* ExtraIterator.from([4, 5, 6])
|
|
274
|
-
* .
|
|
274
|
+
* .prependAll([1, 2, 3])
|
|
275
275
|
* .toArray()
|
|
276
276
|
* // returns [1, 2, 3, 4, 5, 6]
|
|
277
277
|
*/
|
|
278
|
-
|
|
278
|
+
prependAll(items) {
|
|
279
279
|
return ExtraIterator.from(function* () {
|
|
280
280
|
yield* items;
|
|
281
281
|
yield* this;
|
|
@@ -351,9 +351,9 @@ export class ExtraIterator extends Iterator {
|
|
|
351
351
|
/**
|
|
352
352
|
* Groups the elements in this iterator into groups of variable size.
|
|
353
353
|
*
|
|
354
|
-
* This method calls the provided predicate function for each pair of adjacent elements in this iterator.
|
|
355
|
-
* return `true` if the elements should belong to the same group, or `false` if they should belong
|
|
356
|
-
* groups.
|
|
354
|
+
* This method calls the provided predicate function for each pair of adjacent elements in this iterator. The
|
|
355
|
+
* function should return `true` if the elements should belong to the same group, or `false` if they should belong
|
|
356
|
+
* to different groups.
|
|
357
357
|
*
|
|
358
358
|
* The resulting iterator yields arrays of elements that belong to the same group.
|
|
359
359
|
*
|
|
@@ -373,7 +373,7 @@ export class ExtraIterator extends Iterator {
|
|
|
373
373
|
let chunk = [first.value];
|
|
374
374
|
for (let left = first, right, index = 0; right = this.next(), !right.done; left = right, index++) {
|
|
375
375
|
if (predicate(left.value, right.value, index, chunk)) {
|
|
376
|
-
chunk.push(
|
|
376
|
+
chunk.push(right.value);
|
|
377
377
|
}
|
|
378
378
|
else {
|
|
379
379
|
yield chunk;
|
|
@@ -489,8 +489,7 @@ export class ExtraIterator extends Iterator {
|
|
|
489
489
|
*/
|
|
490
490
|
splice(startIndex, deleteCount, ...newItems) {
|
|
491
491
|
if (startIndex < 0) {
|
|
492
|
-
return ExtraIterator.from(this.toArray()
|
|
493
|
-
.toSpliced(startIndex, deleteCount, ...newItems));
|
|
492
|
+
return ExtraIterator.from(this.toArray().toSpliced(startIndex, deleteCount, ...newItems));
|
|
494
493
|
}
|
|
495
494
|
return ExtraIterator.from(function* () {
|
|
496
495
|
for (let index = 0, next; next = this.next(), !next.done; index++) {
|
|
@@ -504,7 +503,8 @@ export class ExtraIterator extends Iterator {
|
|
|
504
503
|
}.call(this));
|
|
505
504
|
}
|
|
506
505
|
/**
|
|
507
|
-
*
|
|
506
|
+
* If this iterator is empty, returns an iterator with the provided element as its only element; otherwise, it
|
|
507
|
+
* returns a copy of this iterator.
|
|
508
508
|
*/
|
|
509
509
|
defaultIfEmpty(provider) {
|
|
510
510
|
return ExtraIterator.from(function* () {
|
|
@@ -528,9 +528,6 @@ export class ExtraIterator extends Iterator {
|
|
|
528
528
|
loop(times = Infinity) {
|
|
529
529
|
return ExtraIterator.from(function* () {
|
|
530
530
|
const values = this.toArray();
|
|
531
|
-
if (values.length === 0) {
|
|
532
|
-
return;
|
|
533
|
-
}
|
|
534
531
|
for (let i = 0; i < times; i++) {
|
|
535
532
|
yield* values;
|
|
536
533
|
}
|
|
@@ -663,8 +660,8 @@ export class ExtraIterator extends Iterator {
|
|
|
663
660
|
*
|
|
664
661
|
* @example
|
|
665
662
|
*
|
|
666
|
-
* ExtraIterator.from([1, 2, 3]).
|
|
667
|
-
* ExtraIterator.from([1, 2, 3, 1]).
|
|
663
|
+
* ExtraIterator.from([1, 2, 3]).testUnique() // returns true
|
|
664
|
+
* ExtraIterator.from([1, 2, 3, 1]).testUnique() // returns false
|
|
668
665
|
*/
|
|
669
666
|
testUnique(mapper) {
|
|
670
667
|
const seen = new Set();
|
package/dist/index.test.js
CHANGED
|
@@ -7,12 +7,24 @@ describe(ExtraIterator.name, () => {
|
|
|
7
7
|
const iterator = ExtraIterator.from(array);
|
|
8
8
|
expect(iterator.toArray()).toEqual(array);
|
|
9
9
|
});
|
|
10
|
+
it('should create an ExtraIterator from an "array-like" object', () => {
|
|
11
|
+
const arrayLike = { 0: 'a', 1: 'b', 2: 'c', length: 3 };
|
|
12
|
+
const iterator = ExtraIterator.from(arrayLike);
|
|
13
|
+
expect(iterator.toArray()).toEqual(['a', 'b', 'c']);
|
|
14
|
+
});
|
|
10
15
|
it('should zip two iterators', () => {
|
|
11
16
|
const a = ExtraIterator.from([1, 2, 3]);
|
|
12
17
|
const b = ExtraIterator.from(['a', 'b', 'c']);
|
|
13
|
-
const zipped =
|
|
18
|
+
const zipped = a.zip(b);
|
|
14
19
|
expect(zipped.toArray()).toEqual([[1, 'a'], [2, 'b'], [3, 'c']]);
|
|
15
20
|
});
|
|
21
|
+
it('should zip three iterators', () => {
|
|
22
|
+
const a = ExtraIterator.from([1, 2, 3]);
|
|
23
|
+
const b = ExtraIterator.from(['a', 'b', 'c']);
|
|
24
|
+
const c = ExtraIterator.from([true, false, true]);
|
|
25
|
+
const zipped = ExtraIterator.zip(a, b, c);
|
|
26
|
+
expect(zipped.toArray()).toEqual([[1, 'a', true], [2, 'b', false], [3, 'c', true]]);
|
|
27
|
+
});
|
|
16
28
|
it('should count from 0 to a given number', () => {
|
|
17
29
|
const iterator = ExtraIterator.count().take(5);
|
|
18
30
|
expect(iterator.toArray()).toEqual([0, 1, 2, 3, 4]);
|
|
@@ -42,6 +54,10 @@ describe(ExtraIterator.name, () => {
|
|
|
42
54
|
const iterator = ExtraIterator.from([1, 2, 3, 4]).take(2);
|
|
43
55
|
expect(iterator.toArray()).toEqual([1, 2]);
|
|
44
56
|
});
|
|
57
|
+
it('should take the last values of the sequence', () => {
|
|
58
|
+
const iterator = ExtraIterator.from([1, 2, 3, 4]).take(-2);
|
|
59
|
+
expect(iterator.toArray()).toEqual([3, 4]);
|
|
60
|
+
});
|
|
45
61
|
it('should drop a given number of values', () => {
|
|
46
62
|
const iterator = ExtraIterator.from([1, 2, 3, 4]).drop(2);
|
|
47
63
|
expect(iterator.toArray()).toEqual([3, 4]);
|
|
@@ -54,9 +70,15 @@ describe(ExtraIterator.name, () => {
|
|
|
54
70
|
const iterator = ExtraIterator.from([1, 2, 3]);
|
|
55
71
|
expect(iterator.first()).toBe(1);
|
|
56
72
|
});
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
73
|
+
describe(ExtraIterator.prototype.last.name, () => {
|
|
74
|
+
it('should return the last value if the iterator is not empty', () => {
|
|
75
|
+
const iterator = ExtraIterator.from([1, 2, 3]);
|
|
76
|
+
expect(iterator.last()).toBe(3);
|
|
77
|
+
});
|
|
78
|
+
it('should return undefined if the iterator is empty', () => {
|
|
79
|
+
const iterator = ExtraIterator.empty();
|
|
80
|
+
expect(iterator.last()).toBeUndefined();
|
|
81
|
+
});
|
|
60
82
|
});
|
|
61
83
|
it('should return a value at a specific index', () => {
|
|
62
84
|
const iterator = ExtraIterator.from([1, 2, 3]);
|
|
@@ -92,6 +114,10 @@ describe(ExtraIterator.name, () => {
|
|
|
92
114
|
const iterator = ExtraIterator.from([2, 3]).prepend(1);
|
|
93
115
|
expect(iterator.toArray()).toEqual([1, 2, 3]);
|
|
94
116
|
});
|
|
117
|
+
it('should prepend multiple values to the iterator', () => {
|
|
118
|
+
const iterator = ExtraIterator.from([4, 5, 6]).prependAll([1, 2, 3]);
|
|
119
|
+
expect(iterator.toArray()).toEqual([1, 2, 3, 4, 5, 6]);
|
|
120
|
+
});
|
|
95
121
|
it('should append a value to the iterator', () => {
|
|
96
122
|
const iterator = ExtraIterator.from([1, 2]).append(3);
|
|
97
123
|
expect(iterator.toArray()).toEqual([1, 2, 3]);
|
|
@@ -114,9 +140,19 @@ describe(ExtraIterator.name, () => {
|
|
|
114
140
|
const iterator = ExtraIterator.from([1, 2, 3, 4]).splice(1, 2, 5, 6);
|
|
115
141
|
expect(iterator.toArray()).toEqual([1, 5, 6, 4]);
|
|
116
142
|
});
|
|
117
|
-
it('should
|
|
118
|
-
const iterator = ExtraIterator.
|
|
119
|
-
expect(iterator.toArray()).toEqual([
|
|
143
|
+
it('should splice values from the end of the iterator', () => {
|
|
144
|
+
const iterator = ExtraIterator.from([1, 2, 3, 4]).splice(-3, 2, 5, 6);
|
|
145
|
+
expect(iterator.toArray()).toEqual([1, 5, 6, 4]);
|
|
146
|
+
});
|
|
147
|
+
describe('defaultIfEmpty', () => {
|
|
148
|
+
it('should provide a default value if the iterator is empty', () => {
|
|
149
|
+
const iterator = ExtraIterator.empty().defaultIfEmpty(() => 42);
|
|
150
|
+
expect(iterator.toArray()).toEqual([42]);
|
|
151
|
+
});
|
|
152
|
+
it('should relay the iterator itself if it is not empty', () => {
|
|
153
|
+
const iterator = ExtraIterator.from([1, 2, 3]).defaultIfEmpty(() => 42);
|
|
154
|
+
expect(iterator.toArray()).toEqual([1, 2, 3]);
|
|
155
|
+
});
|
|
120
156
|
});
|
|
121
157
|
it('should group values by a key', () => {
|
|
122
158
|
const iterator = ExtraIterator.from(['apple', 'banana', 'apricot']);
|
|
@@ -171,6 +207,16 @@ describe(ExtraIterator.name, () => {
|
|
|
171
207
|
.toArray();
|
|
172
208
|
expect(result).toEqual([[1, 1], [2], [3, 3, 3], [2, 2]]);
|
|
173
209
|
});
|
|
210
|
+
it('should chunk using a key selector function', () => {
|
|
211
|
+
const result = ExtraIterator.from(['apple', 'apricot', 'banana', 'avocado'])
|
|
212
|
+
.chunkWith((lhs, rhs) => lhs[0] === rhs[0])
|
|
213
|
+
.toArray();
|
|
214
|
+
expect(result).toEqual([['apple', 'apricot'], ['banana'], ['avocado']]);
|
|
215
|
+
});
|
|
216
|
+
it('should build an empty iterator for an empty iterator', () => {
|
|
217
|
+
const result = ExtraIterator.from([]).chunkWith((lhs, rhs) => lhs === rhs).toArray();
|
|
218
|
+
expect(result).toEqual([]);
|
|
219
|
+
});
|
|
174
220
|
});
|
|
175
221
|
it('should create a chain of responsibility function', () => {
|
|
176
222
|
const humanizeDuration = ExtraIterator.from([
|
|
@@ -191,9 +237,18 @@ describe(ExtraIterator.name, () => {
|
|
|
191
237
|
const chain = handlers.toChainOfResponsibilityFunction(next => next());
|
|
192
238
|
expect(() => chain()).toThrow();
|
|
193
239
|
});
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
240
|
+
describe(ExtraIterator.prototype.loop.name, () => {
|
|
241
|
+
it('should repeat values', () => {
|
|
242
|
+
const iterator = ExtraIterator.from([1, 2, 3]).loop(3);
|
|
243
|
+
expect(iterator.toArray()).toEqual([1, 2, 3, 1, 2, 3, 1, 2, 3]);
|
|
244
|
+
});
|
|
245
|
+
it('should yield an empty iterator if the count is equal to or lower than 0', () => {
|
|
246
|
+
expect(ExtraIterator.from([1, 2, 3]).loop(0).toArray()).toEqual([]);
|
|
247
|
+
expect(ExtraIterator.from([1, 2, 3]).loop(-1).toArray()).toEqual([]);
|
|
248
|
+
expect(ExtraIterator.from([1, 2, 3]).loop(-3).toArray()).toEqual([]);
|
|
249
|
+
expect(ExtraIterator.from([1, 2, 3]).loop(-4).toArray()).toEqual([]);
|
|
250
|
+
expect(ExtraIterator.from([1, 2, 3]).loop(-99999).toArray()).toEqual([]);
|
|
251
|
+
});
|
|
197
252
|
});
|
|
198
253
|
describe(ExtraIterator.range.name, () => {
|
|
199
254
|
it('should iterate over ranges', () => {
|
|
@@ -216,4 +271,42 @@ describe(ExtraIterator.name, () => {
|
|
|
216
271
|
expect(() => ExtraIterator.range(0, 10, { step: 0 }).toArray()).toThrow();
|
|
217
272
|
});
|
|
218
273
|
});
|
|
274
|
+
it('should count the number of elements in the iterator', () => {
|
|
275
|
+
expect(ExtraIterator.from([1, 2, 3]).count()).toBe(3);
|
|
276
|
+
expect(ExtraIterator.empty().count()).toBe(0);
|
|
277
|
+
});
|
|
278
|
+
describe(ExtraIterator.prototype.testUnique.name, () => {
|
|
279
|
+
it('should return true if all values are unique', () => {
|
|
280
|
+
expect(ExtraIterator.from([1, 2, 3]).testUnique()).toBe(true);
|
|
281
|
+
});
|
|
282
|
+
it('should return false if there are duplicate values', () => {
|
|
283
|
+
expect(ExtraIterator.from([1, 2, 2, 3]).testUnique()).toBe(false);
|
|
284
|
+
});
|
|
285
|
+
it('should return true for an empty iterator', () => {
|
|
286
|
+
expect(ExtraIterator.empty().testUnique()).toBe(true);
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
describe(ExtraIterator.prototype.withEach.name, () => {
|
|
290
|
+
it('should perform a side effect for each value', () => {
|
|
291
|
+
const sideEffects = [];
|
|
292
|
+
const iterator = ExtraIterator.from([1, 2, 3]).withEach(x => void sideEffects.push(x));
|
|
293
|
+
expect(iterator.toArray()).toEqual([1, 2, 3]);
|
|
294
|
+
expect(sideEffects).toEqual([1, 2, 3]);
|
|
295
|
+
});
|
|
296
|
+
it('should not perform side effects if the iterator is not consumed', () => {
|
|
297
|
+
const sideEffects = [];
|
|
298
|
+
ExtraIterator.from([1, 2, 3]).withEach(x => void sideEffects.push(x));
|
|
299
|
+
expect(sideEffects).toEqual([]);
|
|
300
|
+
});
|
|
301
|
+
it('should perform side effects even if the iterator is only partially consumed', () => {
|
|
302
|
+
const sideEffects = [];
|
|
303
|
+
const iterator = ExtraIterator.from([1, 2, 3]).withEach(x => void sideEffects.push(x));
|
|
304
|
+
iterator.next();
|
|
305
|
+
expect(sideEffects).toEqual([1]);
|
|
306
|
+
});
|
|
307
|
+
it('should perform side effects on objects', () => {
|
|
308
|
+
const iterator = ExtraIterator.from([{ value: 1 }, { value: 2 }, { value: 3 }]).withEach(obj => obj.value *= 2);
|
|
309
|
+
expect(iterator.toArray()).toEqual([{ value: 2 }, { value: 4 }, { value: 6 }]);
|
|
310
|
+
});
|
|
311
|
+
});
|
|
219
312
|
});
|
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.11.
|
|
6
|
+
"version": "0.11.1",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": "./dist/index.js",
|