UNPKG

@universis/percentile-ranking

Version:

Percentile ranking is a vital part of any student information system. It indicates how well a student performed in comparison to the students in the specific norm group, for example, in the same grade, class, or graduation event. This package implements t

160 lines (158 loc) 6.44 kB
class PercentileRanking { constructor(grades) { this.grades = grades; this._gradeRank = new Map(); } get grades() { return this._grades; } set grades(gradeArray) { this._grades = gradeArray; } /** * This calculates the simple percentile rank of all the * grades that were provided during the initialization * of the object */ simplePercentileCalculation() { this.grades.map(grade => { this.calculateSingleSimpleRank(grade); }); } /** * This calculates the complex percentile rank of all the * grades that were provided during the initialization * of the object */ complexPercentileCalculation() { this.grades.map(grade => { this.calculateSingleComplexRank(grade); }); } /** * Given a grade, calculate the simple percentile rank for that grade * It checks to see if the grade is already included in the initial grade * array and if it is, it checks if there is already a value in the cached * map. If not, it calculates the rank treating smaller and equal grades with * the same coefficient. * If the item isn't included in the initial array, it just creates a new array * and adds the new item to that array instead of overwriting the initial and * proceeds with the same calculation * @param {Grades} item */ calculateSingleSimpleRank(item) { if (this.grades.map(x => x.student).includes(item.student)) { if (this._gradeRank.has(item.grade)) { item.percentileRank = this._gradeRank.get(item.grade); } else { item.percentileRank = this.grades.filter(x => x.grade <= item.grade).length / this.grades.length; } } else { let _grades = [...this.grades, item]; item.percentileRank = _grades.filter(x => x.grade <= item.grade).length / _grades.length; } this._gradeRank.set(item.grade, item.percentileRank); } /** * Given a grade, calculate the simple percentile rank for that grade * It checks to see if the grade is already included in the initial grade * array and if it is, it checks if there is already a value in the cached * map. If not, it calculates the rank treating smaller grades with * the coefficient equal to 1 and the equal grades with a coefficient of 0.5. * If the item isn't included in the initial array, it just creates a new array * and adds the new item to that array instead of overwriting the initial and * proceeds with the same calculation * @param {Grades} item */ calculateSingleComplexRank(item) { if (this.grades.map(x => x.student).includes(item.student)) { if (this._gradeRank.has(item.grade)) { item.percentileRank = this._gradeRank.get(item.grade); } else { item.percentileRank = (this.grades.filter(x => x.grade < item.grade).length + (0.5 * this.grades.filter(x => x.grade === item.grade).length)) / this.grades.length; } } else { let _grades = [...this.grades, item]; item.percentileRank = (_grades.filter(x => x.grade < item.grade).length + (0.5 * _grades.filter(x => x.grade === item.grade).length)) / _grades.length; } this._gradeRank.set(item.grade, item.percentileRank); } /** * Given a grades array, this calculates the simple percentile * rank of all the grades that were provided * @param {Array<Grades>} grades */ static simplePercentileCalculation(grades) { let _gradeRank = new Map(); grades.map(grade => { this.calculateSingleSimpleRank(grades, grade, _gradeRank); }); } /** * Given a grades array, this calculates the complex percentile * rank of all the grades that were provided * @param {Array<Grades>} grades */ static complexPercentileCalculation(grades) { let _gradeRank = new Map(); grades.map(grade => { this.calculateSingleComplexRank(grades, grade, _gradeRank); }); } /** * Given an array of grades, a grade, and an optional cache map, * calculate the simple percentile rank of the given grade and * save the result to the cache map. * @param {Array<Grades>} grades * @param {Grades} item * @param {Map<number,number>} _gradeRank */ static calculateSingleSimpleRank(grades, item, _gradeRank) { if (grades.map(x => x.student).includes(item.student)) { if (_gradeRank && _gradeRank.has(item.grade)) { item.percentileRank = _gradeRank.get(item.grade); } else { item.percentileRank = grades.filter(x => x.grade <= item.grade).length / grades.length; } } else { let _grades = [...grades, item]; item.percentileRank = _grades.filter(x => x.grade <= item.grade).length / _grades.length; } if (_gradeRank) { _gradeRank.set(item.grade, item.percentileRank); } } /** * Given an array of grades, a grade, and an optional cache map, * calculate the complex percentile rank of the given grade and * save the result to the cache map. * @param {Array<Grades>} grades * @param {Grades} item * @param {Map<number, number>} _gradeRank */ static calculateSingleComplexRank(grades, item, _gradeRank) { if (grades.map(x => x.student).includes(item.student)) { if (_gradeRank && _gradeRank.has(item.grade)) { item.percentileRank = _gradeRank.get(item.grade); } else { item.percentileRank = (grades.filter(x => x.grade < item.grade).length + (0.5 * grades.filter(x => x.grade === item.grade).length)) / grades.length; } } else { let _grades = [...grades, item]; item.percentileRank = (_grades.filter(x => x.grade < item.grade).length + (0.5 * _grades.filter(x => x.grade === item.grade).length)) / _grades.length; } if (_gradeRank) { _gradeRank.set(item.grade, item.percentileRank); } } } export { PercentileRanking }; //# sourceMappingURL=index.esm.js.map