Skip to content

Instantly share code, notes, and snippets.

@stephen-lazaro
Last active October 5, 2018 15:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stephen-lazaro/897353209b19719e21224335034ffbd1 to your computer and use it in GitHub Desktop.
Save stephen-lazaro/897353209b19719e21224335034ffbd1 to your computer and use it in GitHub Desktop.
// 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