Group students by grade, and list each group in order.
What to build
A report produced by combining sorting, filtering and mapping.
Requirements
- Grade A is a mark of 80 or more, B is 60 or more, and C is anything lower.
- Print the groups in the order A, B, C. Do not print a group with no students.
- In each group, order the students by mark from highest to lowest. Equal marks are ordered by name, alphabetically.
- Format each line as in the example.
Input
Several lines, each NAME MARK.
Output
One line for each grade that has students.
Constraints
There are from 1 to 100 students. Marks are whole numbers from 0 to 100. Names are letters only, and are all different.
Example
Input:
Rahim 82
Mitu 91
Arif 67
Output:
A: Mitu(91), Rahim(82)
B: Arif(67)
Why it works
Sorting once at the start means that every group is already in order when it is filtered out, because filter keeps the order it finds. A compare function can handle two rules by moving on to the second only when the first gives 0.
Examples
Rahim 82 Mitu 91 Arif 67
A: Mitu(91), Rahim(82) B: Arif(67)
Sadia 12
C: Sadia(12)
Hints
Hint 1
A mark of 80 or more is A, 60 or more is B, and anything lower is C.
Hint 2
Sort first, by mark from high to low and then by name, using localeCompare for ties.
Hint 3
Then filter once for each grade, and skip a grade with no students.
Solution
Show one correct solution (try it yourself first)
const students = [];
let line = prompt();
while (line !== null) {
const [name, mark] = line.split(" ");
students.push({ name, mark: Number(mark) });
line = prompt();
}
function gradeOf(mark) {
if (mark >= 80) return "A";
if (mark >= 60) return "B";
return "C";
}
const sorted = [...students].sort((a, b) => b.mark - a.mark || a.name.localeCompare(b.name));
for (const grade of ["A", "B", "C"]) {
const group = sorted.filter((s) => gradeOf(s.mark) === grade);
if (group.length > 0) {
console.log(`${grade}: ${group.map((s) => `${s.name}(${s.mark})`).join(", ")}`);
}
}