Skip to content

Instantly share code, notes, and snippets.

@odyss009
Created March 1, 2017 15:56
Show Gist options
  • Save odyss009/05a9e5f0773f2c09accacd1083e1de24 to your computer and use it in GitHub Desktop.
Save odyss009/05a9e5f0773f2c09accacd1083e1de24 to your computer and use it in GitHub Desktop.
filterReducer, mapReducer, composeReducers, transducer
// 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);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment