Sal
Sal

Reputation: 107

Average of array inside an object

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

Answers (6)

Doston
Doston

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

Iosif
Iosif

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

Nithish
Nithish

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

Ilijanovic
Ilijanovic

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

Greedo
Greedo

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

JMP
JMP

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

Related Questions