Reducers: Update percentile logic - move percentiles to after standard reducers (#86004)

* baldm0mma/pth_fix2/ move percentiles to after standard reducers

* baldm0mma/pth_fix2/ update ordinal suffix

---------

Co-authored-by: nmarrs <nathanielmarrs@gmail.com>
This commit is contained in:
Jev Forsberg 2024-04-17 07:01:13 -06:00 committed by GitHub
parent 0a12ad0084
commit f9af4675ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 20 deletions

View File

@ -252,17 +252,19 @@ describe('Stats Calculators', () => {
expect(reduce(someNulls, ReducerID.count)).toEqual(4);
});
for (let i = 1; i < 100; i++) {
it(`can reduce the ${i}th percentile`, () => {
it('can reduce to percentiles', () => {
// This `Array.from` will build an array of elements from 1 to 99
const percentiles = [...Array.from({ length: 99 }, (_, i) => i + 1)];
percentiles.forEach((percentile) => {
const preciseStats = reduceField({
field: createField(
'x',
Array.from({ length: 101 }, (_, index) => index)
),
reducers: [(ReducerID as Record<string, ReducerID>)[`p${i}`]],
reducers: [(ReducerID as Record<string, ReducerID>)[`p${percentile}`]],
});
expect(preciseStats[`p${i}`]).toEqual(i);
expect(preciseStats[`p${percentile}`]).toEqual(percentile);
});
}
});
});

View File

@ -402,27 +402,34 @@ export const fieldReducers = new Registry<FieldReducerInfo>(() => [
}),
preservesUnits: false,
},
...buildPercentileReducers(),
]);
for (let i = 1; i < 100; i++) {
const percentile = i / 100;
const id = `p${i}` as ReducerID;
// This `Array.from` will build an array of elements from 1 to 99
const buildPercentileReducers = (percentiles = [...Array.from({ length: 99 }, (_, i) => i + 1)]) => {
const percentileReducers: FieldReducerInfo[] = [];
const nth = (n: number) =>
n > 3 && n < 21 ? 'th' : n % 10 === 1 ? 'st' : n % 10 === 2 ? 'nd' : n % 10 === 3 ? 'rd' : 'th';
const name = `${i}${nth(i)} percentile`;
const description = `${i}${nth(i)} percentile value`;
fieldReducers.register({
id: id,
name: name,
description: description,
standard: false,
reduce: (field: Field, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs => {
return { [id]: calculatePercentile(field, percentile, ignoreNulls, nullAsZero) };
},
preservesUnits: true,
percentiles.forEach((p) => {
const percentile = p / 100;
const id = `p${p}` as ReducerID;
const name = `${p}${nth(p)} %`;
const description = `${p}${nth(p)} percentile value`;
percentileReducers.push({
id: id,
name: name,
description: description,
standard: false,
reduce: (field: Field, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs => {
return { [id]: calculatePercentile(field, percentile, ignoreNulls, nullAsZero) };
},
preservesUnits: true,
});
});
}
return percentileReducers;
};
// Used for test cases
export const defaultCalcs: FieldCalcs = {