/
uniqAsync.ts
64 lines (63 loc) · 2.36 KB
/
uniqAsync.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import { AsyncGen, AsyncOperator, AsyncSeq } from '../../AsyncSeq';
import { asyncDefaultSelector } from '../../utils';
/**
* Returns a deduplicated sequence.
*
* ```typescript
* const result1 = await fromAsAsync([1,1,3,2,4,4,4,1,5]).pipe(
* uniqAsync()
* ).toArrayAsync();
* //result1: [1,3,2,4,5]
*
* const source = [
* {groupKey: {mainKey: 1, subKey: 'a'}, value: "test1"},
* {groupKey: {mainKey: 2, subKey: 'b'}, value: "test2"},
* {groupKey: {mainKey: 1, subKey: 'a'}, value: "test3"},
* {groupKey: {mainKey: 1, subKey: 'c'}, value: "test4"},
* ];
*
* const result2 = await fromAsAsync(source).pipe(
* uniqAsync(
* async i => i.groupKey,
* async one => one.mainKey + one.subKey
* )
* ).toArrayAsync();
*
* // result2: [
* // {"groupKey":{"mainKey":1,"subKey":"a"},"value":"test1"},
* // {"groupKey":{"mainKey":2,"subKey":"b"},"value":"test2"},
* // {"groupKey":{"mainKey":1,"subKey":"c"},"value":"test4"},
* // ]
* ```
*
* For more information on *keySelector* and *comparableValueForKey*, please refer to [Equality Strategy](/#equality-strategy).
*
* The implementation of *asyncDefaultSelector* is as follows.
* ```typescript
* export const asyncDefaultSelector = (target: any): any => Promise.resolve(target);
* ```
*
* @param keySelector Function to return the object used to check Equality.
* @param comparableValueForKey This function returns an object that is unique to the key selected by *keySelector*.
* It is recommended to return a string or number.
* @returns Operator function.
* @typeParam T Source element type.
* @typeParam TKey key type.
* @typeParam TComparableValue The type of the return value returned by *comparableValueForKey*.
* @category Async Operators
*/
export const uniqAsync = <T, TComparableValue, TKey = T>(
keySelector: (target: T) => Promise<TKey> = asyncDefaultSelector,
comparableValueForKey?: (key: TKey) => Promise<TComparableValue>
): AsyncOperator<T> =>
async function* uniqAsync(source: AsyncSeq<T>): AsyncGen<T> {
const appeared: Set<TKey | TComparableValue> = new Set();
const createKeyValue = async (i: T) => (comparableValueForKey ? comparableValueForKey(await keySelector(i)) : keySelector(i));
for await (const i of source) {
const keyValue = await createKeyValue(i);
if (!appeared.has(keyValue)) {
yield i;
appeared.add(keyValue);
}
}
};