@thi.ng/transducers
Version:
Collection of ~170 lightweight, composable transducers, reducers, generators, iterators for functional data transformations
67 lines (66 loc) • 1.99 kB
JavaScript
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
};