UNPKG

@codibre/fluent-iterable

Version:

Provides LINQ-like fluent api operations for iterables and async iterables (ES2018+).

59 lines (58 loc) 2.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.combineRecipe = combineRecipe; const prepare_1 = require("../types-internal/prepare"); const utils_1 = require("../utils"); function getMapItems(m, keyB, resolver) { return (u) => resolver(keyB(u), (key) => { let p = m.get(key); if (!p) { p = []; m.set(key, p); } p.push(u); return m; }); } function getMapResult(m, keyA, resolver) { return (t) => resolver(keyA(t), (key) => { const result = m.get(key); return result !== undefined ? 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, resolver)), () => flatten.call(filter.call(map.call(itThis, getMapResult(m, keyA, resolver)), utils_1.identity))); }; } function combineRecipe(combineFuncs) { const { flatten, map } = combineFuncs; const innerJoin = getInnerJoin(combineFuncs); const combineNN = getCombineNN(map, flatten); return function (iterable, baseKeyA, baseKeyB) { if (!baseKeyA === !!baseKeyB) { throw new Error('Both key mapper must be informed, or no one'); } return baseKeyA ? innerJoin(this, iterable, baseKeyA, baseKeyB) : combineNN(this, iterable); }; }