name:
src/main/js/formulas/statistical/AVERAGE.ts
-rw-r--r--
1642
1import { isNotNull } from "../../utils/Other";
2import { DivException } from "../../errors/DivException";
3import { SheetColumnRowKey } from "../../models/common/SheetColumnRowKey";
4import { Complex } from "../../models/common/Types";
5import { Converters } from "../../utils/Converters";
6import { Counter } from "../../utils/Counter";
7import { Mappers } from "../../utils/Mappers";
8import { Reducers } from "../../utils/Reducers";
9import { AbstractFormula } from "../AbstractFormula";
10import { FormulaName } from "../FormulaName";
11
12export class AVERAGE extends AbstractFormula {
13 static SELF: AVERAGE = new AVERAGE();
14 NAME = FormulaName.AVERAGE;
15
16 internal(origin: SheetColumnRowKey, ...values: Array<Complex>) {
17 AbstractFormula.checkAtLeastLength(values.length, 1, this.NAME);
18 const counter = new Counter<number>();
19 const sum = values
20 .map(this.lookup)
21 .map(Mappers.flattenGridsToArrays) // 1, "2", [null, 1, "99", "Text.", null, true]
22 .map(Mappers.checkArrayValuesForErrors) // Throw if there are errors.
23 .map(Mappers.filterArrayValuesByIsCoercableToNumeric) // 1, 2, [1, "99", true]
24 .map(Mappers.ensureAllAreArrays) // [1], [2], [1, "99", true]
25 .reduce(Reducers.join) // [1, 2, 1, "99", true]
26 .filter(isNotNull) // [1, 2, 1, "99", true]
27 .map(Mappers.throwErrors)
28 .map(Converters.toNumber) // [1, 2, 1, 99, 1]
29 .map((value) => counter.count(value))
30 .reduce(Reducers.sum, 0);
31 if (counter.getCount() === 0) {
32 return new DivException("Formula AVERAGE caused an error when attempting to divide by zero.");
33 }
34 return sum / counter.getCount();
35 }
36}