-
Notifications
You must be signed in to change notification settings - Fork 0
/
toLookup.ts
81 lines (74 loc) · 2.85 KB
/
toLookup.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import { IndexedSelector } from "../types/IndexedSelector";
import { MapFactory } from "../types/MapFactory";
export function _toLookup<T, TKey>(
src: Iterable<T>,
keySelector: IndexedSelector<T, TKey>,
mapFactory?: MapFactory<TKey>
): Map<TKey, Iterable<T>>;
export function _toLookup<T, TKey, TValue>(
src: Iterable<T>,
keySelector: IndexedSelector<T, TKey>,
valueSelector: IndexedSelector<T, TValue>,
mapFactory?: MapFactory<TKey>
): Map<TKey, Iterable<TValue>>;
export function _toLookup<T, TKey, TValue = T>(
src: Iterable<T>,
keySelector: IndexedSelector<T, TKey>,
valueSelectorOrMapFactory?: IndexedSelector<T, TValue> | MapFactory<TKey>,
mapFactoryMaybe?: MapFactory<TKey>
): Map<TKey, Iterable<T | TValue>> {
let mapFactory: MapFactory<TKey> | undefined;
let valueSelector: IndexedSelector<T, TValue> | undefined;
if (typeof valueSelectorOrMapFactory === "object") {
mapFactory = valueSelectorOrMapFactory;
} else {
mapFactory = mapFactoryMaybe;
if (typeof valueSelectorOrMapFactory === "function") {
valueSelector = valueSelectorOrMapFactory;
}
}
const mapFac: () => Map<TKey, Iterable<T | TValue>> = mapFactory
? mapFactory.createMap.bind(mapFactory)
: () => new Map();
const vs: (v: T, i: number) => T | TValue = valueSelector ?? ((x) => x);
const map: Map<TKey, Iterable<T | TValue>> = mapFac();
let i = 0;
for (const item of src) {
const currentIdx = i++;
const key = keySelector(item, currentIdx);
const arr: (T | TValue)[] =
(map.get(key) as (T | TValue)[] | undefined) ?? new Array<T | TValue>();
map.set(key, arr);
arr.push(vs(item, currentIdx));
}
return map;
}
export function toLookup<T, TKey>(
keySelector: IndexedSelector<T, TKey>,
mapFactory?: MapFactory<TKey>
): (src: Iterable<T>) => Map<TKey, Iterable<T>>;
export function toLookup<T, TKey, TValue>(
keySelector: IndexedSelector<T, TKey>,
valueSelector: IndexedSelector<T, TValue>,
mapFactory?: MapFactory<TKey>
): (src: Iterable<T>) => Map<TKey, Iterable<TValue>>;
export function toLookup<T, TKey, TValue = T>(
keySelector: IndexedSelector<T, TKey>,
valueSelectorOrMapFactory?: IndexedSelector<T, TValue> | MapFactory<TKey>,
mapFactoryMaybe?: MapFactory<TKey>
): (src: Iterable<T>) => Map<TKey, Iterable<T | TValue>> {
let mapFactory: MapFactory<TKey> | undefined;
let valueSelector: IndexedSelector<T, TValue> | undefined;
if (typeof valueSelectorOrMapFactory === "object") {
mapFactory = valueSelectorOrMapFactory;
} else {
mapFactory = mapFactoryMaybe;
if (typeof valueSelectorOrMapFactory === "function") {
valueSelector = valueSelectorOrMapFactory;
}
}
return valueSelector
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
(src) => _toLookup(src, keySelector, valueSelector!, mapFactory)
: (src) => _toLookup(src, keySelector, mapFactory);
}