Skip to content

Instantly share code, notes, and snippets.

@bryanerayner
Created April 10, 2017 00:25
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 bryanerayner/ac62c7e260ea3f682f920a597179dffb to your computer and use it in GitHub Desktop.
Save bryanerayner/ac62c7e260ea3f682f920a597179dffb to your computer and use it in GitHub Desktop.
This method returns an array of items which have changed
/**
* This runs aggregate_reduce through a sequence, in an immutable, repeatable fashion.
*
* First, elements in the sequence which were not processed, are run through evaluate().
*
* Next, elements which still have to be processed, are run through aggregateReduce().
*
* Both the aggregate, and the full sequence, are returned after execution.
*
* @param initialAggregate The initial aggregate
* @param pile The pile of input which will reduce into the resulting aggregate. It is expected that this pile is presented in sequence, beginning with already processed events.
* @param evaluate The method which calculates both the next aggregate, and any additional elements which are created as a result.
* @param wasProcessed A method which indicates, whether or not a method has already been run.
* @returns A tuple containing the final aggregate, and the full sequence of events which were run to compute it.
*/
export function immutableAggregateReduce<A, T>(
initialAggregate: A,
pile: T[],
evaluate: (aggregate: A, element: T)=>[A, T[]],
wasProcessed: (element: T)=>boolean
): [A, T[]] {
let mutableAggregate = initialAggregate;
let mutablePile = [].concat(pile);
let elementSequence: T[] = [];
const isEmpty = <L>(v: L[])=>!v.length;
while(!isEmpty(pile)) {
let element = pile.shift();
elementSequence.push(element);
let elementWasProcessed = wasProcessed(element);
let [nextAggregate, nextSequence] = evaluate(mutableAggregate, element);
if (!elementWasProcessed) {
nextSequence.forEach(v=>pile.push(v));
}
mutableAggregate = nextAggregate;
}
return [mutableAggregate, elementSequence];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment