From 69ce47d0b477afcff77464a586b613dbea9a7859 Mon Sep 17 00:00:00 2001 From: Andrei Dumitrescu <5057797+andreidcm@users.noreply.github.com> Date: Thu, 27 Aug 2020 22:15:37 +0200 Subject: [PATCH] feat: Update "reduce" to allow uncurried call --- src/reduce/reduce.js | 53 ++++++++++++++++++++++++++++++--------- src/reduce/reduce.test.js | 14 +++++++++-- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/reduce/reduce.js b/src/reduce/reduce.js index ea87a78..b045286 100644 --- a/src/reduce/reduce.js +++ b/src/reduce/reduce.js @@ -1,25 +1,54 @@ +import { pipe } from "../pipe/pipe" + +const _reduce = (fn, defaultAcc, _source) => { + let acc = defaultAcc + const source = Array.isArray(_source) ? _source : [_source] + + for (let i = 0, length = source.length; i < length; i++) { + acc = Array.isArray(fn) + ? pipe(...fn)(acc, source[i], i, source) + : fn(acc, source[i], i, source) + } + + return acc +} + /** * Apply a function against an accumulator and each element in the array (from * left to right) to reduce it to a single value. * - * @param {Function} fn Reduce function - * @param {Object} defaultAcc The default acc - * @param {Array} source Source input + * @param {Function} fn Reduce function + * @param {Object} defaultAcc Default accumulator value + * @param {Array} source Source input * * @return {mixed} * * @tag Array * @signature (fn: Function, defaultAcc: mixed) => (source: Array): mixed + * @signature (fn: Function, defaultAcc: mixed, source: Array): mixed + * + * @example + * const sum = (acc, item) => acc + item + * + * reduce(sum, 0, [1, 2]) + * // => 3 */ -const reduce = (fn, defaultAcc) => source => { - let acc = defaultAcc - const sourceArray = Array.isArray(source) ? source : [source] - - for (let i = 0, length = sourceArray.length; i < length; i++) { - acc = fn(acc, sourceArray[i], i, sourceArray) +export const reduce = (...params) => { + /* + * @signature (fn: Fn|Fn[], defaultAcc: mixed) => (source: []): mixed + * + * reduce(sum, 0)([1, 2]) + * // => 3 + */ + if (params.length < 3) { + return source => _reduce(params[0], params[1], source) } - return acc + /* + * @signature (fn: Fn|Fn[], defaultAcc: mixed, source: []): mixed + * + * reduce(sum, 0, [1, 2]) + * // => 3 + */ + return _reduce(...params) } - -export { reduce } diff --git a/src/reduce/reduce.test.js b/src/reduce/reduce.test.js index 745639b..4216db1 100644 --- a/src/reduce/reduce.test.js +++ b/src/reduce/reduce.test.js @@ -2,7 +2,17 @@ import test from "tape" import { reduce } from ".." test("reduce", t => { - t.equals(reduce((acc, next) => acc + next, 0)([1, 2, 3]), 6, "Sum an array") + t.equals( + reduce((acc, item) => acc + item, 0, [1, 2, 3]), + 6, + "Sum an array - uncurried" + ) + + t.equals( + reduce((acc, next) => acc + next, 0)([1, 2, 3]), + 6, + "Sum an array-curried" + ) t.equals( reduce((acc, next) => acc + next, 0)(12), @@ -17,7 +27,7 @@ test("reduce", t => { ) t.equals( - reduce((acc = 0, next) => acc + next, 0)([]), + reduce((acc, next) => acc + next, 0)([]), 0, "Reducing empty array return default acc" )