Reputation: 107
I have an array of objects that contains the name and marks of students. like below
I need to calculate the 'average' marks each student has and compare the 'average' marks to get the top student. I am trying like below, I am not getting what am I missing?
var Students = [
{
name: "Bob",
marks: [78,80,89,90,68]
},
{
name: "Alin",
marks: [87,60,59,70,68]
},
{
name: "bikash",
marks: [82,60,79,60,80]
}
];
for (let i = 0; i < Students.length; i++){
var average = Students[i].reduce((total, next)=> total + next.marks) /2
}
console.log(average)
I need to have average marks of each students to compare the results of All students
Upvotes: 1
Views: 1032
Reputation: 637
If you are looking for traditional loop:
const Students = [{
name: 'Bob',
marks: [78, 80, 89, 90, 68],
},
{
name: 'Alin',
marks: [87, 60, 59, 70, 68],
},
{
name: 'bikash',
marks: [82, 60, 79, 60, 80],
},
];
var average;
for (let i = 0; i < Students.length; i++){
var marks = Students[i]["marks"];
var total = 0;
console.log(marks);
for (var j = 0; j < marks.length; j++ ) {
total += marks[j];
}
average = total / marks.length;
// answer for question in the comment
var msg = Students[i]["name"] + " has average mark: " + average;
console.log(msg)
}
console.log(average)
Upvotes: 0
Reputation: 822
Maybe this:
const students = [{
name: 'Bob',
marks: [78, 80, 89, 90, 68],
},
{
name: 'Alin',
marks: [87, 60, 59, 70, 68],
},
{
name: 'bikash',
marks: [82, 60, 79, 60, 80],
},
];
const topStudent = students
.map(student => ({
...student,
averageMark: student.marks.reduce((a, b) => a + b, 0) / student.marks.length,
}))
.sort((a, b) => a.averageMark - b.averageMark)
.pop();
console.log(topStudent);
Upvotes: 3
Reputation: 6019
Below is one of the ways of finding the student with maximum average using Array.reduce
, Array.map
.
var Students = [{name:"Alin",marks:[87,60,59,70,68]},{name:"Bob",marks:[78,80,89,90,68]},{name:"bikash",marks:[82,60,79,60,80]}];
const getTopStudent = (students) => {
//Find the avg of the current student
const formattedStudents = students.map(student => ({...student, avg: student.marks.reduce((t, m) => t+m, 0)/student.marks.length}))
return formattedStudents.reduce((res, student) => {
//Check if the avg of the student in res object is less than the avg of the current student, then return current student.
if((res.avg || 0) < student.avg){
return {
...student
}
}
return res;
}, {})
}
console.log(getTopStudent(Students))
.as-console-wrapper {
max-height: 100% !important;
}
Note: In the above example I have not considered if there are more than one student having the same avg.
Below is the example which will return all the students if the average is same
var Students = [{name:"Alin",marks:[87,60,59,70,68]},{name:"Bob",marks:[78,80,89,90,68]},{name:"bikash",marks:[82,60,79,60,80]},{name:"Joey",marks:[78,80,84,90,73]}];
const getTopStudent = (students) => {
const formattedStudents = students.map(student => ({ ...student,
avg: student.marks.reduce((t, m) => t + m, 0) / student.marks.length
}))
const finalRes = formattedStudents.reduce((res, student) => {
//if the res.avg is less than current student avg then update the res object with the new avg and the students
if ((res.avg || 0) < student.avg) {
return {
avg: student.avg,
students: [{ ...student }]
}
} else if ((res.avg || 0) === student.avg) {
//If average of the current student is same as res.avg, then push the current student to the res.students
res.students.push(student);
return res;
}
return res;
}, {});
return finalRes.students;
}
//More than one student with max avg
console.log(getTopStudent(Students));
//One student with max avg
console.log(getTopStudent(Students.slice(0,3)));
.as-console-wrapper {
max-height: 100% !important;
}
Upvotes: 0
Reputation: 14914
Here we go. It returns you an array of objects with the name and the average score of the students.
Its also sorted from highest average to lowest
let arr = [
{
name: "Bob",
marks: [78,80,89,90,68]
},
{
name: "Alin",
marks: [87,60,59,70,68]
},
{
name: "bikash",
marks: [82,60,79,60,80]
}
]
let averages = arr.map(({ marks, name }) => {
let average = marks.reduce((a,v) => a + v) / marks.length
return { name , average }
}).sort((a,b) => b.average - a.average);
let [{ name }] = averages;
console.log(averages)
console.log("top student: ", name);
Upvotes: 1
Reputation: 3549
You can also extract it in a function:
var Students = [
{
name: "Bob",
marks: [78,80,89,90,68]
},
{
name: "Alin",
marks: [87,60,59,70,68]
},
{
name: "bikash",
marks: [82,60,79,60,80]
}
];
// Student avarage
var averages = []
for (let i = 0; i < Students.length; i++){
var avg = average(Students[i].marks);
console.log(Students[i].name + ": " + avg)
averages.push(avg)
}
// Total average
console.log("total average: " + average(averages))
function average(array) {
return array.reduce((total, mark) => total + mark, 0) / array.length;
}
Upvotes: 0
Reputation: 4467
You need to reduce
the marks
array of each Student
, not a Student
object, as this is not an array.
next
is the next value in the array, not the next item in Students
.
Finally, place the console.log
line inside the loop so to get all the results printed out.
var Students = [
{
name: "Bob",
marks: [78,80,89,90,68]
},
{
name: "Alin",
marks: [87,60,59,70,68]
},
{
name: "bikash",
marks: [82,60,79,60,80]
}
];
for (let i = 0; i < Students.length; i++){
var average = Students[i].marks.reduce((total, next)=> total + next) / Students[i].marks.length;
console.log(average);
}
Upvotes: 0