krl-stdlib
Version:
Standard library for KRL
75 lines (70 loc) • 1.84 kB
text/typescript
import * as _ from "lodash";
import * as krl from "./krl";
function toFloat(v: any) {
return krl.toNumberOrNull(v) || 0;
}
const aggregators: { [op: string]: (vals: any[]) => any } = {
max(values) {
return _.max(_.map(values, toFloat));
},
min(values) {
return _.min(_.map(values, toFloat));
},
sum(values) {
return _.reduce(
_.map(values, toFloat),
function (sum, n) {
return sum + n;
},
0
);
},
avg(values) {
var sum = _.reduce(
_.map(values, toFloat),
function (sum, n) {
return sum + n;
},
0
);
return sum / _.size(values);
},
push(values) {
return values;
},
};
export function aggregateEvent(
state: any,
op: string,
pairs: [string, string][]
): any {
state = state || {};
const stateStates = Array.isArray(state.states) ? state.states : [];
const isStart = stateStates.indexOf("start") >= 0;
const isEnd = stateStates.indexOf("end") >= 0;
let newAggregates: { [name: string]: any[] } = {};
let newSetting: { [name: string]: any } = {};
for (const [name, value] of pairs) {
let vals: any[] =
state.aggregates && Array.isArray(state.aggregates[name])
? state.aggregates[name]
: [];
if (isStart) {
// reset the aggregated values every time the state machine resets
vals = [value];
} else if (isEnd) {
// keep a sliding window every time the state machine hits end again i.e. select when repeat ..
vals = _.tail(vals.concat([value]));
} else {
vals = vals.concat([value]);
}
newAggregates[name] = vals;
if (aggregators[op]) {
newSetting[name] = aggregators[op](vals);
}
}
return Object.assign({}, state, {
aggregates: newAggregates,
setting: Object.assign({}, state.setting, newSetting),
});
}