extra-iterator 0.3.0 → 0.4.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 +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +13 -2
- package/dist/index.test.d.ts +1 -0
- package/dist/index.test.js +121 -0
- package/package.json +8 -3
package/README.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
|
|
|
31
31
|
flatMap<U>(callback: (value: T, index: number) => Iterator<U, unknown, undefined> | Iterable<U, unknown, undefined>): ExtraIterator<U>;
|
|
32
32
|
flatten(): T extends Iterable<infer U> ? ExtraIterator<U> : never;
|
|
33
33
|
groupBy<K extends string | symbol>(callbackfn: (value: T, index: number) => K): Record<K, T[]>;
|
|
34
|
-
|
|
34
|
+
unique(keyProvider?: (value: T) => unknown): ExtraIterator<T>;
|
|
35
35
|
compact(): ExtraIterator<Exclude<T, null | undefined>>;
|
|
36
36
|
withEach(callbackfn: (value: T, index: number) => void): ExtraIterator<T>;
|
|
37
37
|
first(): T | undefined;
|
|
@@ -52,5 +52,6 @@ export declare class ExtraIterator<T> extends Iterator<T, any, any> {
|
|
|
52
52
|
collect<U>(collectfn: ((iter: Iterable<T>) => U)): U;
|
|
53
53
|
toSortedBy(...keys: (keyof T)[]): T[];
|
|
54
54
|
count(): number;
|
|
55
|
+
uniqueness(mapper?: (value: T) => unknown): boolean;
|
|
55
56
|
}
|
|
56
57
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -95,14 +95,14 @@ export class ExtraIterator extends Iterator {
|
|
|
95
95
|
}
|
|
96
96
|
return result;
|
|
97
97
|
}
|
|
98
|
-
|
|
98
|
+
unique(keyProvider = value => value) {
|
|
99
99
|
return ExtraIterator.from(function* () {
|
|
100
100
|
const seen = new Set();
|
|
101
101
|
for (let item; item = this.next(), !item.done;) {
|
|
102
102
|
const key = keyProvider(item.value);
|
|
103
103
|
if (!seen.has(key)) {
|
|
104
|
-
yield item.value;
|
|
105
104
|
seen.add(key);
|
|
105
|
+
yield item.value;
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
}.call(this));
|
|
@@ -273,4 +273,15 @@ export class ExtraIterator extends Iterator {
|
|
|
273
273
|
}
|
|
274
274
|
return count;
|
|
275
275
|
}
|
|
276
|
+
uniqueness(mapper) {
|
|
277
|
+
const seen = new Set();
|
|
278
|
+
for (let next; next = this.next(), !next.done;) {
|
|
279
|
+
const value = mapper ? mapper(next.value) : next.value;
|
|
280
|
+
if (seen.has(value)) {
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
seen.add(value);
|
|
284
|
+
}
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
276
287
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { ExtraIterator } from './index';
|
|
2
|
+
import { describe, it } from 'node:test';
|
|
3
|
+
import { expect } from 'expect';
|
|
4
|
+
describe('ExtraIterator', () => {
|
|
5
|
+
it('should create an ExtraIterator from an array', () => {
|
|
6
|
+
const array = [1, 2, 3];
|
|
7
|
+
const iterator = ExtraIterator.from(array);
|
|
8
|
+
expect(iterator.toArray()).toEqual(array);
|
|
9
|
+
});
|
|
10
|
+
it('should zip two iterators', () => {
|
|
11
|
+
const a = ExtraIterator.from([1, 2, 3]);
|
|
12
|
+
const b = ExtraIterator.from(['a', 'b', 'c']);
|
|
13
|
+
const zipped = ExtraIterator.zip(a, b);
|
|
14
|
+
expect(zipped.toArray()).toEqual([[1, 'a'], [2, 'b'], [3, 'c']]);
|
|
15
|
+
});
|
|
16
|
+
it('should count from 0 to a given number', () => {
|
|
17
|
+
const iterator = ExtraIterator.count(5);
|
|
18
|
+
expect(iterator.toArray()).toEqual([0, 1, 2, 3, 4]);
|
|
19
|
+
});
|
|
20
|
+
it('should repeat a value a given number of times', () => {
|
|
21
|
+
const iterator = ExtraIterator.repeat(3, 'x');
|
|
22
|
+
expect(iterator.toArray()).toEqual(['x', 'x', 'x']);
|
|
23
|
+
});
|
|
24
|
+
it('should filter values based on a predicate', () => {
|
|
25
|
+
const iterator = ExtraIterator.from([1, 2, 3, 4]).filter(x => x % 2 === 0);
|
|
26
|
+
expect(iterator.toArray()).toEqual([2, 4]);
|
|
27
|
+
});
|
|
28
|
+
it('should map values using a callback function', () => {
|
|
29
|
+
const iterator = ExtraIterator.from([1, 2, 3]).map(x => x * 2);
|
|
30
|
+
expect(iterator.toArray()).toEqual([2, 4, 6]);
|
|
31
|
+
});
|
|
32
|
+
it('should take a limited number of values', () => {
|
|
33
|
+
const iterator = ExtraIterator.from([1, 2, 3, 4]).take(2);
|
|
34
|
+
expect(iterator.toArray()).toEqual([1, 2]);
|
|
35
|
+
});
|
|
36
|
+
it('should drop a given number of values', () => {
|
|
37
|
+
const iterator = ExtraIterator.from([1, 2, 3, 4]).drop(2);
|
|
38
|
+
expect(iterator.toArray()).toEqual([3, 4]);
|
|
39
|
+
});
|
|
40
|
+
it('should flatten nested iterables', () => {
|
|
41
|
+
const iterator = ExtraIterator.from([[1, 2], [3, 4]]).flatten();
|
|
42
|
+
expect(iterator.toArray()).toEqual([1, 2, 3, 4]);
|
|
43
|
+
});
|
|
44
|
+
it('should return the first value', () => {
|
|
45
|
+
const iterator = ExtraIterator.from([1, 2, 3]);
|
|
46
|
+
expect(iterator.first()).toBe(1);
|
|
47
|
+
});
|
|
48
|
+
it('should return the last value', () => {
|
|
49
|
+
const iterator = ExtraIterator.from([1, 2, 3]);
|
|
50
|
+
expect(iterator.last()).toBe(3);
|
|
51
|
+
});
|
|
52
|
+
it('should return a value at a specific index', () => {
|
|
53
|
+
const iterator = ExtraIterator.from([1, 2, 3]);
|
|
54
|
+
expect(iterator.at(1)).toBe(2);
|
|
55
|
+
});
|
|
56
|
+
it('should interpose a separator between values', () => {
|
|
57
|
+
const iterator = ExtraIterator.from([1, 2, 3]).interpose(0);
|
|
58
|
+
expect(iterator.toArray()).toEqual([1, 0, 2, 0, 3]);
|
|
59
|
+
});
|
|
60
|
+
it('should chunk values into groups of a given size', () => {
|
|
61
|
+
const iterator = ExtraIterator.from([1, 2, 3, 4]).chunk(2);
|
|
62
|
+
expect(iterator.toArray()).toEqual([[1, 2], [3, 4]]);
|
|
63
|
+
});
|
|
64
|
+
it('should remove duplicate values', () => {
|
|
65
|
+
const iterator = ExtraIterator.from([1, 2, 2, 3]).unique();
|
|
66
|
+
expect(iterator.toArray()).toEqual([1, 2, 3]);
|
|
67
|
+
});
|
|
68
|
+
it('should compact values by removing null and undefined', () => {
|
|
69
|
+
const iterator = ExtraIterator.from([1, null, 2, undefined, 3]).compact();
|
|
70
|
+
expect(iterator.toArray()).toEqual([1, 2, 3]);
|
|
71
|
+
});
|
|
72
|
+
it('should concatenate two iterators', () => {
|
|
73
|
+
const a = ExtraIterator.from([1, 2]);
|
|
74
|
+
const b = ExtraIterator.from([3, 4]);
|
|
75
|
+
const concatenated = a.concat(b);
|
|
76
|
+
expect(concatenated.toArray()).toEqual([1, 2, 3, 4]);
|
|
77
|
+
});
|
|
78
|
+
it('should prepend a value to the iterator', () => {
|
|
79
|
+
const iterator = ExtraIterator.from([2, 3]).prepend(1);
|
|
80
|
+
expect(iterator.toArray()).toEqual([1, 2, 3]);
|
|
81
|
+
});
|
|
82
|
+
it('should append a value to the iterator', () => {
|
|
83
|
+
const iterator = ExtraIterator.from([1, 2]).append(3);
|
|
84
|
+
expect(iterator.toArray()).toEqual([1, 2, 3]);
|
|
85
|
+
});
|
|
86
|
+
it('should take values while a predicate is true', () => {
|
|
87
|
+
const iterator = ExtraIterator.from([1, 2, 3, 4]).takeWhile(x => x < 3);
|
|
88
|
+
expect(iterator.toArray()).toEqual([1, 2]);
|
|
89
|
+
});
|
|
90
|
+
it('should drop values while a predicate is true', () => {
|
|
91
|
+
const iterator = ExtraIterator.from([1, 2, 3, 4]).dropWhile(x => x < 3);
|
|
92
|
+
expect(iterator.toArray()).toEqual([3, 4]);
|
|
93
|
+
});
|
|
94
|
+
it('should interleave two iterators', () => {
|
|
95
|
+
const a = ExtraIterator.from([1, 3]);
|
|
96
|
+
const b = ExtraIterator.from([2, 4]);
|
|
97
|
+
const interleaved = a.interleave(b);
|
|
98
|
+
expect(interleaved.toArray()).toEqual([1, 2, 3, 4]);
|
|
99
|
+
});
|
|
100
|
+
it('should splice values in the iterator', () => {
|
|
101
|
+
const iterator = ExtraIterator.from([1, 2, 3, 4]).splice(1, 2, 5, 6);
|
|
102
|
+
expect(iterator.toArray()).toEqual([1, 5, 6, 4]);
|
|
103
|
+
});
|
|
104
|
+
it('should provide a default value if the iterator is empty', () => {
|
|
105
|
+
const iterator = ExtraIterator.empty().defaultIfEmpty(() => 42);
|
|
106
|
+
expect(iterator.toArray()).toEqual([42]);
|
|
107
|
+
});
|
|
108
|
+
it('should group values by a key', () => {
|
|
109
|
+
const iterator = ExtraIterator.from(['apple', 'banana', 'apricot']);
|
|
110
|
+
const grouped = iterator.groupBy(word => word[0]);
|
|
111
|
+
expect(grouped).toEqual({
|
|
112
|
+
a: ['apple', 'apricot'],
|
|
113
|
+
b: ['banana'],
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
it('should collect values using a custom collector', () => {
|
|
117
|
+
const iterator = ExtraIterator.from([1, 2, 3]);
|
|
118
|
+
const sum = iterator.collect(iter => Array.from(iter).reduce((a, b) => a + b, 0));
|
|
119
|
+
expect(sum).toBe(6);
|
|
120
|
+
});
|
|
121
|
+
});
|
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.4.0",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": "./dist/index.js",
|
|
@@ -13,13 +13,18 @@
|
|
|
13
13
|
"dist"
|
|
14
14
|
],
|
|
15
15
|
"scripts": {
|
|
16
|
-
"test": "
|
|
16
|
+
"test": "run-s test:types test:unit",
|
|
17
|
+
"test:types": "tsc --noEmit",
|
|
18
|
+
"test:unit": "node --import=tsx --test **/*.test.ts",
|
|
17
19
|
"build": "tsc",
|
|
18
20
|
"prebuild": "rimraf dist",
|
|
19
|
-
"prepack": "
|
|
21
|
+
"prepack": "run-s test build"
|
|
20
22
|
},
|
|
21
23
|
"devDependencies": {
|
|
24
|
+
"expect": "^29.7.0",
|
|
25
|
+
"npm-run-all": "^4.1.5",
|
|
22
26
|
"rimraf": "^6.0.1",
|
|
27
|
+
"tsx": "^4.19.3",
|
|
23
28
|
"typescript": "^5.8.3"
|
|
24
29
|
},
|
|
25
30
|
"keywords": [
|