A full Reducer (or AsyncReducer) is an object that allows the accumulator's type to differ from the type of the values in the iterable. This is useful for maintaining complex state (like a sum and a count simultaneously).
Sync Reducer
Pass an object to reduce() with:
create: A function to produce the initial accumulator value.add: A function to combine the current accumulator with the next value.finish (optional): A function to transform the final accumulator.
Note: reduce() with a full reducer does not return an optional because create handles the zero-value case.
Async Reducer
Pass an object to reduceAsync() with:
create: An async function to produce the initial accumulator.add: An async function to combine the accumulator and value.combine (optional): An async function to combine two accumulators (useful for concurrent reductions).finish (optional): An async function to transform the final accumulator.
// Sync Full Reducer (e.g., calculating mean)
import { map, pipe, reduce } from 'lfi'
const meanSquares = numbers =>
pipe(
numbers,
map(number => number * number),
reduce({
create: () => ({ sum: 0, count: 0 }),
add: ({ sum, count }, number) => ({ sum: sum + number, count: count + 1 }),
finish: ({ sum, count }) => (count === 0 ? NaN : sum / count),
}),
)
// Async Full Reducer
import { asAsync, mapAsync, pipe, reduceAsync } from 'lfi'
const meanSquares = async numbers => {
return await pipe(
asAsync(numbers),
mapAsync(number => number * number),
reduceAsync({
create: async () => ({ sum: 0, count: 0 }),
add: async ({ sum, count }, number) => ({ sum: sum + number, count: count + 1 }),
combine: async (acc1, acc2) => ({
sum: acc1.sum + acc2.sum,
count: acc1.count + acc2.count
}),
finish: async ({ sum, count }) => (count === 0 ? NaN : sum / count),
}),
)
}