UNPKG

fast-iterable

Version:

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

77 lines (76 loc) 2.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.flatJoinRecipe = void 0; const base_1 = require("./../types/base"); const is_iterable_1 = require("../is-iterable"); function flattable(value) { return typeof value !== 'string' && (0, is_iterable_1.isIterable)(value); } function getNextIterable(current, path, nextIndex) { let item = current; if (flattable(item)) { return [item, nextIndex]; } while (nextIndex < path.length) { item = item[path[nextIndex]]; nextIndex++; if (flattable(item)) { break; } } return [item, nextIndex]; } function fillMiddleFieldsFactory(oldItem, start, nextIndex, path) { return (x) => { let current = oldItem; for (let i = start; i < nextIndex; i++) { current = current[path[i]]; if (!flattable(current)) { x[path[i]] = current; } } return x; }; } function fillMiddleToHeadFieldsFactory(oldItem, start, nextIndex, path) { const fillMiddleFields = fillMiddleFieldsFactory(oldItem, start, nextIndex, path); return (sub) => { const newItem = fillMiddleFields({}); newItem[base_1.head] = sub; return newItem; }; } function mapRoot(iterable, map, key, value) { return map.call(iterable, (x) => { x[key] = value; return x; }); } function flatMap(item, ingredients, path, nextIndex) { const oldItem = item; const { flatten, map } = ingredients; const start = nextIndex; const result = getNextIterable(item, path, nextIndex); item = result[0]; nextIndex = result[1]; if (nextIndex < path.length) { return flatten.call(item, (sub) => { const mapped = map.call(flatMap(sub, ingredients, path, nextIndex), fillMiddleFieldsFactory(oldItem, start, nextIndex, path)); return mapRoot(mapped, map, nextIndex > 0 ? path[nextIndex - 1] : base_1.tail, sub); }); } const fillMiddleToHeadItems = fillMiddleToHeadFieldsFactory(oldItem, start, nextIndex, path); return flattable(item) ? map.call(item, fillMiddleToHeadItems) : [fillMiddleToHeadItems(item)]; } function flatJoinRecipe(ingredients) { const { map, iterateAll } = ingredients; return function (...path) { return iterateAll(map.call(this, (x) => { const flatted = flatMap(x, ingredients, path, 0); return flattable(x) ? flatted : mapRoot(flatted, map, base_1.tail, x); })); }; } exports.flatJoinRecipe = flatJoinRecipe;