fast-iterable
Version:
Provides LINQ-like fluent api operations for iterables and async iterables (ES2018+).
61 lines (60 loc) • 2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.combineRecipe = void 0;
const prepare_1 = require("../types-internal/prepare");
const utils_1 = require("../utils");
function getMapItems(m, keyB) {
return (u) => {
const key = keyB(u);
let p = m.get(key);
if (!p) {
p = [];
m.set(key, p);
}
p.push(u);
return m;
};
}
function getMapResult(m, keyA) {
return (t) => {
const result = m.get(keyA(t));
return result ? result.map((u) => [t, u]) : undefined;
};
}
function getMapNN(cache, map) {
return ([a, bIt]) => cache.length > 0
? map.call(cache, (b) => [a, b])
: map.call(bIt, (b) => {
cache.push(b);
return [a, b];
});
}
function getCombineNN(map, flatten) {
return function (itThis, iterable) {
const cache = [];
const mapped = map.call(itThis, (a) => [a, iterable]);
return flatten.call(mapped, getMapNN(cache, map));
};
}
function getInnerJoin({ resolver, flatten, forEach, filter, map, }) {
return function (itThis, iterable, baseKeyA, baseKeyB) {
const keyA = (0, prepare_1.prepare)(baseKeyA);
const keyB = (0, prepare_1.prepare)(baseKeyB);
const m = new Map();
return resolver(forEach.call(iterable, getMapItems(m, keyB)), () => flatten.call(filter.call(map.call(itThis, getMapResult(m, keyA)), utils_1.identity)));
};
}
function combineRecipe(combineFuncs) {
const { flatten, map } = combineFuncs;
const innerJoin = getInnerJoin(combineFuncs);
const combineNN = getCombineNN(map, flatten);
return function (iterable, keyA, keyB) {
if (!keyA === !!keyB) {
throw new Error('Both key mapper must be informed, or no one');
}
return keyA
? innerJoin(this, iterable, keyA, keyB)
: combineNN(this, iterable);
};
}
exports.combineRecipe = combineRecipe;