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:

  1. Grouping: First, it groups all scores by student ID using an object where keys are student IDs and values are arrays of scores
  2. Sorting and Filtering: For each student, it sorts their scores in descending order and takes the top num scores
  3. 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.

Updated on: 2026-03-15T23:19:00+05:30

661 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements