Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Finding average of n top marks of each student in JavaScript
Suppose, we have an array of objects that contains information about some students and the marks scored by them over a period of time like this:
const marks = [
{ id: 231, score: 34 },
{ id: 233, score: 37 },
{ id: 231, score: 31 },
{ id: 233, score: 39 },
{ id: 231, score: 44 },
{ id: 233, score: 41 },
{ id: 231, score: 38 },
{ id: 231, score: 31 },
{ id: 233, score: 29 },
{ id: 231, score: 34 },
{ id: 233, score: 40 },
{ id: 231, score: 31 },
{ id: 231, score: 30 },
{ id: 233, score: 38 },
{ id: 231, score: 43 },
{ id: 233, score: 42 },
{ id: 233, score: 28 },
{ id: 231, score: 33 },
];
We are required to write a JavaScript function that takes in one such array as the first argument and a number, say num, as the second argument.
The function should then pick num highest records of each unique student according to the score property and calculate average for each student. If there are not enough records for any student, we should take all of their records into consideration.
And finally, the function should return an object that has the student id as key and their average score as the value.
Solution Approach
The solution involves three main steps:
- Group all scores by student ID
- Sort each student's scores in descending order and take the top N scores
- Calculate the average of those top scores
Implementation
const marks = [
{ id: 231, score: 34 },
{ id: 233, score: 37 },
{ id: 231, score: 31 },
{ id: 233, score: 39 },
{ id: 231, score: 44 },
{ id: 233, score: 41 },
{ id: 231, score: 38 },
{ id: 231, score: 31 },
{ id: 233, score: 29 },
{ id: 231, score: 34 },
{ id: 233, score: 40 },
{ id: 231, score: 31 },
{ id: 231, score: 30 },
{ id: 233, score: 38 },
{ id: 231, score: 43 },
{ id: 233, score: 42 },
{ id: 233, score: 28 },
{ id: 231, score: 33 },
];
const calculateHighestAverage = (marks = [], num = 1) => {
const findHighestAverage = (arr = [], upto = 1) => {
const topScores = arr
.sort((a, b) => b - a)
.slice(0, upto);
return topScores.reduce((acc, val) => acc + val, 0) / topScores.length;
};
const res = {};
// Group scores by student ID
for (const obj of marks) {
const { id, score } = obj;
if (res.hasOwnProperty(id)) {
res[id].push(score);
} else {
res[id] = [score];
}
}
// Calculate average of top N scores for each student
for (const id in res) {
res[id] = findHighestAverage(res[id], num);
}
return res;
};
console.log(calculateHighestAverage(marks, 5));
console.log(calculateHighestAverage(marks, 4));
console.log(calculateHighestAverage(marks));
{ '231': 38.6, '233': 40 }
{ '231': 39.75, '233': 40.5 }
{ '231': 44, '233': 42 }
How It Works
The function works in the following steps:
- Grouping: First, it groups all scores by student ID using an object where keys are student IDs and values are arrays of scores
-
Sorting and Filtering: For each student, it sorts their scores in descending order and takes the top
numscores - Average Calculation: It calculates the average of the selected top scores for each student
Example Usage
-
calculateHighestAverage(marks, 5)- Takes top 5 scores of each student and calculates their average -
calculateHighestAverage(marks, 4)- Takes top 4 scores of each student -
calculateHighestAverage(marks)- Takes only the highest score (default num = 1)
Conclusion
This solution efficiently groups student data, selects top scores, and calculates averages. It handles cases where students have fewer records than requested by taking all available scores.
