-
-
Save stephen-lazaro/897353209b19719e21224335034ffbd1 to your computer and use it in GitHub Desktop.
This file contains 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 characters
// Again, producing an aggregation | |
const makeAggregation = (operation, initial) => ({ | |
operation: operation, | |
initialValue: initial | |
}); | |
// Adjust the combination a bit to be more general | |
// We take _all the aggregations_ and apply them to the prior values _in their index_ and the next value _in their index_ | |
const combineAggregationsReduction = (combined, next) => | |
makeAggregation((prior, nextValue) => | |
// A bit finicky, admittedly | |
[ | |
…combined.operation( | |
prior.slice(0, -1), | |
nextValue | |
), | |
next.operation( | |
prior[prior.length - 1], | |
nextValue | |
) | |
], | |
[…combined.initialValue, next.initialValue] | |
); | |
// We need to wrap the first aggregate's reduction and initial value in arrays | |
// so that we can combine it correctly with the rest. | |
const liftToArray = aggregate => | |
makeAggregation( | |
([a], b) => [aggregate.operation(a, b)], | |
[aggregate.initialValue] | |
); | |
// Reduce our list of aggregates into one aggregate | |
const combineAggregation = aggregates => | |
aggregates.slice(1).reduce( | |
combineAggregationsReduction, | |
liftToArray(aggregates[0]) | |
); | |
// Which we can use to combine multiple aggregates via… | |
// Again, sum balances by aggregating through _summation_ and _starting at zero_ | |
const sumBalances = makeAggregation( | |
(sum, record) => sum + record.balance, | |
0 | |
); | |
// Again, count via just adding 1 every time we see another record | |
const count = makeAggregation( | |
(sum, record) => sum + 1, | |
0 | |
); | |
// Take the product over "variation" whatever that is | |
const productOfVariation = | |
makeAggregation( | |
(product, record) => product * record.variation, | |
1 | |
); | |
// Record the _last_ id in the report via just saving the latest seen | |
const lastIdSeen = | |
makeAggregation( | |
(prior, next) => next.id, | |
null | |
); | |
// And we now run all of the aggregates at once | |
const getAggregates = reports => { | |
const aggregates = combineAggregation([ | |
count, | |
sumBalances, | |
productOfVariation, | |
lastIdSeen | |
]); | |
return reports.reduce( | |
aggregates.operation, | |
aggregates.initialValue | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment