Created
March 1, 2017 15:56
-
-
Save odyss009/05a9e5f0773f2c09accacd1083e1de24 to your computer and use it in GitHub Desktop.
Revisions
-
odyss009 created this gist
Mar 1, 2017 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,52 @@ // Count the iterations let count = 0; const isMultipleOf3Or5 = n => (n % 3 === 0 || n % 5 === 0); // Reducer functions can be composed if we abstract the differences. // The filter's predicate function will need to be abstracted // and curried in for function composition: const filterReducer = predicate => reducer => ( acc, item ) => predicate(item) ? reducer(acc, item) : acc; // The mapping function needs to be abstracted and curried in // to make a map reducer composable: const mapReducer = mapper => reducer => ( acc, item ) => { count++; return reducer(acc, mapper(item)); }; // A shared reducing function abstracts how individual values // get accumulated together: const arrReducer = (acc = [], item) => acc.concat([item]); const double = x => x * 2; // Generic function composition const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x); // Compose curried reducers, passing in the shared // reducing function. The returned reducer can be directly used // by any standard reduce() utility: const composeReducers = reducingFn => (...fns) => compose(...fns)(reducingFn); // Create a transducer: A function which can feed values // through multiple reducers without traversing the collection // more than once. If you filter the collection in a previous // step, the total work will not exceed the size of the filtered // set. const transducer = composeReducers(arrReducer)( filterReducer(isMultipleOf3Or5), mapReducer(x => x + 1), ); // Usage const range = (start, end) => Array.from({ length: end - start + 1 }, (x, i) => i + start); const doubled = range(1,9) .reduce(transducer, []); console.log(doubled, count);