An aggregation (sum, average, …) as four small functions over a state: init → add per value → result.
merge combines two partial states – the result is the same as one pass over all values. That makes groups
(row grouping, pivot) cheap: the state of a group is the merge of the states of its sub-groups, and an average of
averages stays correct ({ sum, count } instead of a number).
The built-in aggregators are in Aggregators; an own aggregator implements this interface and can be used
everywhere a name like "sum" is accepted (AggregatorRef).
add(state, …) and merge(a, b) may change state / a and return it (no allocation per row with millions of
rows); merge never changes b, so a child state can be merged into several parents. Call init() for a fresh
state, e.g. merge(init(), child) for a parent that must not change the child.
Example
// the product of all numbers constproduct: AggregatorIf<number, number> = { name:"product", init: () =>1, add: (state, value) =>typeofvalue === "number" ? state * value : state, merge: (a, b) =>a * b, result:state=>state }; aggregate([{ f:2 }, { f:3 }, { f:7 }], "f", product); // 42
Example
// partial results: the average of two groups is the average of all rows constavg = Aggregators.avg; constnorth = [100, 50, 120].reduce((s, v) =>avg.add(s, v), avg.init()); constsouth = [80, 70, 30].reduce((s, v) =>avg.add(s, v), avg.init()); avg.result(avg.merge(north, south)); // 75 – not the mean of 90 and 60
An aggregation (sum, average, …) as four small functions over a state:
init→addper value →result.mergecombines two partial states – the result is the same as one pass over all values. That makes groups (row grouping, pivot) cheap: the state of a group is the merge of the states of its sub-groups, and an average of averages stays correct ({ sum, count }instead of a number).The built-in aggregators are in Aggregators; an own aggregator implements this interface and can be used everywhere a name like
"sum"is accepted (AggregatorRef).add(state, …)andmerge(a, b)may changestate/aand return it (no allocation per row with millions of rows);mergenever changesb, so a child state can be merged into several parents. Callinit()for a fresh state, e.g.merge(init(), child)for a parent that must not change the child.Example
Example
Since
1.1.94