UNPKG

@thi.ng/transducers

Version:

Collection of ~170 lightweight, composable transducers, reducers, generators, iterators for functional data transformations

67 lines (66 loc) 1.99 kB
import { identity } from "@thi.ng/api/fn"; import { implementsFunction } from "@thi.ng/checks/implements-function"; import { isArrayLike } from "@thi.ng/checks/is-arraylike"; import { isIterable } from "@thi.ng/checks/is-iterable"; import { illegalArity } from "@thi.ng/errors/illegal-arity"; import { isReduced, unreduced } from "./reduced.js"; const __parseArgs = (args) => args.length === 2 ? [void 0, args[1]] : args.length === 3 ? [args[1], args[2]] : illegalArity(args.length); function reduce(...args) { const rfn = args[0]; const init = rfn[0]; const complete = rfn[1]; const reduce2 = rfn[2]; args = __parseArgs(args); const acc = args[0] == null ? init() : args[0]; const src = args[1]; return unreduced( complete( implementsFunction(src, "$reduce") ? src.$reduce(reduce2, acc) : isArrayLike(src) ? __reduceArray(reduce2, acc, src) : __reduceIterable(reduce2, acc, src) ) ); } function reduceRight(...args) { const [init, complete, reduce2] = args[0]; args = __parseArgs(args); let acc = args[0] == null ? init() : args[0]; const src = args[1]; for (let i = src.length; i-- > 0; ) { acc = reduce2(acc, src[i]); if (isReduced(acc)) { acc = acc.deref(); break; } } return unreduced(complete(acc)); } const __reduceArray = (rfn, acc, src) => { for (let i = 0, n = src.length; i < n; i++) { acc = rfn(acc, src[i]); if (isReduced(acc)) { acc = acc.deref(); break; } } return acc; }; const __reduceIterable = (rfn, acc, src) => { for (let x of src) { acc = rfn(acc, x); if (isReduced(acc)) { acc = acc.deref(); break; } } return acc; }; const reducer = (init, rfn) => [init, identity, rfn]; const $$reduce = (rfn, args) => { const n = args.length - 1; return isIterable(args[n]) ? args.length > 1 ? reduce(rfn.apply(null, args.slice(0, n)), args[n]) : reduce(rfn(), args[0]) : void 0; }; export { $$reduce, reduce, reduceRight, reducer };