Interface AggregatorIf<S, R>

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
const product: AggregatorIf<number, number> = {
name: "product",
init: () => 1,
add: (state, value) => typeof value === "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
const avg = Aggregators.avg;
const north = [100, 50, 120].reduce((s, v) => avg.add(s, v), avg.init());
const south = [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

Since

1.1.94

Type Parameters

  • S = any

    the state

  • R = unknown

    the result

Hierarchy

  • AggregatorIf

Properties

Methods

Properties

name: string

The name, e.g. "sum" – the built-in ones use their AggregatorName.

Methods

  • Combines two partial states (a first, then b – matters for first/last); may change a and returns the combined state; never changes b.

    Parameters

    • a: S
    • b: S

    Returns S