UNPKG

@codibre/fluent-iterable

Version:

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

67 lines (66 loc) 2.87 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.incPredicate = incPredicate; exports.distinctRecipe = distinctRecipe; const utils_1 = require("../utils"); const types_internal_1 = require("../types-internal"); const ordered_operation_recipe_1 = require("./ordered-operation-recipe"); const prepare_1 = require("../types-internal/prepare"); function inc(map, y) { const result = (map.get(y) || 0) + 1; map.set(y, result); return result; } function incPredicate(resolver, mapper, maxOcurrences) { const map = new Map(); return (x) => resolver(mapper(x), (y) => inc(map, y) <= maxOcurrences); } const nonChosen = Symbol('nonChosen'); function orderedDistinctRecipe({ map, resolver, partition, filterOrAll, hasLessOrExactly, reduce, }) { const ordered = (0, ordered_operation_recipe_1.orderedOperationRecipe)(map, resolver, partition); return function distinct(mapper, choose, maxOcurrences) { const partitioned = map.call(ordered.call(this, mapper), (x) => map.call(x, (y) => y[1])); if (typeof choose === 'function') { return map.call(partitioned, (x) => reduce.call(x, (acc, y) => { return acc === nonChosen ? y : choose(acc, y); }, nonChosen)); } return filterOrAll.call(partitioned, (part) => hasLessOrExactly.call(part, maxOcurrences)); }; } function chooseDistinctRecipe({ forEach, resolver }) { return function distinct(mapper, choose) { const map = new Map(); return resolver(forEach.call(this, (x) => { const k = mapper(x); const old = map.get(k); const newOne = old === undefined ? x : choose(old, x); if (old !== newOne) { map.set(k, newOne); } }), () => map.values()); }; } function distinctRecipe(ingredients) { const ordered = orderedDistinctRecipe(ingredients); const choose = chooseDistinctRecipe(ingredients); const { filterOrAll, resolver } = ingredients; return function distinct(baseMapper = utils_1.identity, maxOcurrencesOrChoose, maxOcurrences = 1) { const typeCheck = typeof maxOcurrencesOrChoose; if (typeof baseMapper === 'number') { maxOcurrences = baseMapper; baseMapper = utils_1.identity; } else if (typeCheck === 'number') { maxOcurrences = maxOcurrencesOrChoose; } const mapper = (0, prepare_1.prepare)(baseMapper); if ((0, types_internal_1.isAnyOrderAssured)(mapper, this)) { return ordered.call(this, mapper, maxOcurrencesOrChoose, maxOcurrences); } if (typeCheck !== 'function') { return filterOrAll.call(this, incPredicate(resolver, mapper, maxOcurrences)); } return choose.call(this, mapper, maxOcurrencesOrChoose); }; }