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
JavaScript R- eturn Array Item(s) With Largest Score
We have an array of arrays that contains the marks scored by some students in different subjects. We need to write a function that returns the top scorer(s) for each subject, handling cases where multiple students have the same highest score.
Problem Setup
Given this input data:
const arr = [
['Math', 'John', 100],
['Math', 'Jake', 89],
['Math', 'Amy', 93],
['Science', 'Jake', 89],
['Science', 'John', 89],
['Science', 'Amy', 83],
['English', 'John', 82],
['English', 'Amy', 81],
['English', 'Jake', 72]
];
We want to return an array of objects with one object per subject containing the top scorer(s):
[
{ "Subject": "Math",
"Top": [
{ Name: "John", Score: 100}
]
},
{ "Subject": "Science",
"Top": [
{ Name: "Jake", Score: 89},
{ Name: "John", Score: 89}
]
},
{ "Subject": "English",
"Top": [
{ Name: "John", Score: 82}
]
}
]
Solution Using Array.reduce()
The solution uses reduce() to iterate through the data and build the result array:
const arr = [
['Math', 'John', 100],
['Math', 'Jake', 89],
['Math', 'Amy', 93],
['Science', 'Jake', 89],
['Science', 'John', 89],
['Science', 'Amy', 83],
['English', 'John', 82],
['English', 'Amy', 81],
['English', 'Jake', 72]
];
const groupScore = arr => {
return arr.reduce((acc, val) => {
const [subject, name, score] = val;
const existingIndex = acc.findIndex(el => el['Subject'] === subject);
if (existingIndex !== -1) {
// Subject already exists
if (score > acc[existingIndex]["Top"][0]["score"]) {
// New high score - replace all
acc[existingIndex]["Top"] = [{
"name": name, "score": score
}];
} else if (score === acc[existingIndex]["Top"][0]["score"]) {
// Tie for high score - add to list
acc[existingIndex]["Top"].push({
"name": name, "score": score
});
}
} else {
// New subject
acc.push({
"Subject": subject,
"Top": [{"name": name, "score": score}]
});
}
return acc;
}, []);
};
console.log(JSON.stringify(groupScore(arr), undefined, 2));
[
{
"Subject": "Math",
"Top": [
{
"name": "John",
"score": 100
}
]
},
{
"Subject": "Science",
"Top": [
{
"name": "Jake",
"score": 89
},
{
"name": "John",
"score": 89
}
]
},
{
"Subject": "English",
"Top": [
{
"name": "John",
"score": 82
}
]
}
]
How It Works
The algorithm processes each student record and:
- Destructures each array element into subject, name, and score
-
Checks if the subject already exists using
findIndex() - Compares scores - if higher, replaces the top scorers; if equal, adds to the list
- Creates new entries for subjects not yet processed
Key Points
- Handles ties by keeping multiple top scorers for the same subject
- Uses array destructuring for cleaner code
- Efficiently finds existing subjects with
findIndex() - Returns properly formatted JSON structure
Conclusion
This solution effectively groups student scores by subject and identifies top performers, handling tied scores appropriately. The reduce() method provides a clean way to transform the nested array data into the desired object structure.
