@codibre/fluent-iterable
Version:
Provides LINQ-like fluent api operations for iterables and async iterables (ES2018+).
85 lines (84 loc) • 3.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.singleItem = singleItem;
exports.groupRecipe = groupRecipe;
const types_internal_1 = require("../types-internal");
const map_1 = require("../sync/map");
const ordered_operation_recipe_1 = require("./ordered-operation-recipe");
const prepare_1 = require("../types-internal/prepare");
const utils_1 = require("../utils");
function orderedGroupRecipe({ map, resolver, partition, forEach, }) {
const ordered = (0, ordered_operation_recipe_1.orderedOperationRecipe)(map, resolver, partition);
return function (mapper, transformValue) {
const partitioned = ordered.call(this, mapper);
return map.call(partitioned, (part) => {
let key;
const values = [];
const boundValues = values.push.bind(values);
return resolver(forEach.call(part, ([k, v]) => {
key = k;
const iterable = transformValue(k, v, values);
if (iterable) {
return forEach.call(iterable, boundValues);
}
}), () => ({ key, values }));
});
};
}
function reduceGroup({ iterable, reduceAndMap, resolver, mapper, transformValue, forEach, }) {
return reduceAndMap.call(iterable, (g, t) => {
const getG = (0, utils_1.constant)(g);
return resolver(mapper(t), (key) => {
let values = g.get(key);
if (!values) {
values = [];
g.set(key, values);
}
const transformed = transformValue(key, t, values);
return transformed
? resolver(forEach.call(transformed, values.push.bind(values)), getG)
: g;
});
}, new Map(), (x) => x.entries());
}
function nonOrderedGroup({ iterable, reduceAndMap, resolver, mapper, transformValue, forEach, }, iterate) {
const reduced = reduceGroup({
iterable,
reduceAndMap,
resolver,
mapper,
transformValue,
forEach,
});
const resolved = resolver(reduced, (r) => map_1.map.call(r, (([key, values]) => ({
key,
values,
}))));
return iterate(resolved);
}
function singleItem(_k, t) {
return [t];
}
function groupRecipe(ingredients) {
const orderedGroup = orderedGroupRecipe(ingredients);
const { reduceAndMap, resolver, iterate, forEach } = ingredients;
return function (baseMapper, baseTransformValue) {
const mapper = (0, prepare_1.prepare)(baseMapper);
const transformValue = baseTransformValue
? (0, prepare_1.prepare)(baseTransformValue)
: singleItem;
if ((0, types_internal_1.isAnyOrderAssured)(mapper, this)) {
return orderedGroup.call(this, mapper, transformValue);
}
else {
return nonOrderedGroup({
iterable: this,
reduceAndMap,
resolver,
mapper,
transformValue,
forEach,
}, iterate);
}
};
}