-
Notifications
You must be signed in to change notification settings - Fork 0
/
fullOuterGroupJoin.ts
46 lines (43 loc) · 1.49 KB
/
fullOuterGroupJoin.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
import { deferP0, pipeInto as pp } from "ts-functional-pipe";
import { toIterable } from "../helpers/toIterable";
import { IndexedSelector } from "../types/IndexedSelector";
import { MapFactory } from "../types/MapFactory";
import { concat } from "./concat";
import { distinct } from "./distinct";
import { map, _map } from "./map";
import { _toLookup } from "./toLookup";
export function _fullOuterGroupJoin<T, TRight, TKey, TOut>(
src: Iterable<T>,
rightSeq: Iterable<TRight>,
leftKeySelector: IndexedSelector<T, TKey>,
rightKeySelector: IndexedSelector<TRight, TKey>,
selector: (o: Iterable<T>, v: Iterable<TRight>, k: TKey) => TOut,
mapFactory?: MapFactory<TKey>
): Iterable<TOut> {
return toIterable(function* () {
const right = rightSeq;
const leftLookup = _toLookup(src, leftKeySelector, mapFactory);
const rightLookup = _toLookup(right, rightKeySelector, mapFactory);
const rightLookupKeys = _map(rightLookup, ([key, _]) => key);
const allKeys = pp(
leftLookup,
map(([key, _]) => key),
concat(rightLookupKeys),
distinct()
);
const outputValues = pp(
allKeys,
map((key) => ({ key, leftItem: leftLookup.get(key) ?? [] })),
map(({ key, leftItem }) => ({
key,
leftItem,
rightItem: rightLookup.get(key) ?? [],
})),
map((x) => selector(x.leftItem, x.rightItem, x.key))
);
for (const v of outputValues) {
yield v;
}
});
}
export const fullOuterGroupJoin = deferP0(_fullOuterGroupJoin);