2

I have an array of objects that contains the name and marks of students. like below

How can I calculate the 'average' marks each student has and compare the 'average' marks to get the top student. I don’t want to use ES6

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]
  }
];


var average;
var newArray = [];
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;
  newArray.push(average)
  var msg = Students[i]["name"] + " has average mark: " + average;
  console.log(msg)

}

console.log(newArray)

I want to insert the average numbers in an object along with the names like [{name: "Bob", average:89.4},{name: "Alin", average:87.2},{name: "Bikash", average:89.4} ] and sort the object.

Finally, I want to have console.log as Bob is the Top student OR Alin and Bob are the brightest students (in case both of them have the same average number)

5 Answers 5

1

Don't push the average into a new array, add it as a property of Students[i] with Students[i].average = average;.

Then you can sort the array using that property, and print the to students from the sorted array.

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]
  }
];


var average;
for (let i = 0; i < Students.length; i++) {
  var marks = Students[i]["marks"];
  var total = 0;
  for (var j = 0; j < marks.length; j++) {
    total += marks[j];
  }
  average = total / marks.length;
  Students[i].average = average;
  var msg = Students[i]["name"] + " has average mark: " + average;
  console.log(msg)

}
Students.sort((s1, s2) => s2.average - s1.average);
var topAvg = Students[0].average;
var topStudents = Students.filter(s => s.average == topAvg).map(s => s.name).join(", ");
console.log(`Top Students are ${topStudents} with mark ${topAvg}`);

Sign up to request clarification or add additional context in comments.

Comments

1

I have used non ES6 functins, instead traditional for loop and other. Please, find answers for your three questions:

  • Creating a list/array of object in this format: [ { name: 'Alin', average: 68.8 }, ..]

  • Sorting a list/array with average value

  • Getting students with the highest average grade.

         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],
         },
         {
             name: 'Doston',
             marks: [78, 80, 89, 90, 68],
         },
     ];
    
     var average;
     var data = [];
     for (var 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;
    
         var msg = Students[i]["name"] + " has average mark: " + average;
         console.log(msg);
    
         // Answer for the first question:
         var item = {"name": Students[i]["name"], "average": average};
         data.push(item);
    
     }
    
     function compareAndSort(a,b) {
         return parseInt(a.average, 10) - parseInt(b.average, 10);
     }
    
     data.sort(compareAndSort);
    
     // Answer for the second question: sort [ { name: 'Alin', average: 68.8 }, ..]
     console.log(data);
    
     // Answer for the third question - getting students who has highest mark is last since it is sorted
     var bestStudent = data[data.length - 1];
     console.log(bestStudent.name + " has got the highest mark: " + bestStudent.average);
    
     var bestStudents = [bestStudent];
    
     // check if there is only one person with this highest mark
     for (var i = 0; i < data.length; i ++) {
         if (data[i].average >= bestStudent.average && data[i].name !== bestStudent.name) {
             bestStudents.push(data[i]);
         }
     }
    
     // all best students
     console.log(bestStudents);
    

I have added some data to the JSON input, so that you get two best students

2 Comments

const and let are ES6. Use var instead.
@ElectricShadow oh yeah, thanks for correcting me. I am used to working with const and let :) and forgot
0

You don't need an additional array. In theory, calling sort is less efficient than to gather the best student(s) during your loop.

So:

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]}];

var topAverage = -1; 
var topStudents = [];
var newArray = [];
for (let i = 0; i < students.length; i++){
    var marks = students[i].marks;
    var total = 0;
    for (var j = 0; j < marks.length; j++ ) {
        total += marks[j];
    }
    var average = total / marks.length;
    // Keep topAverage & topStudents up to date:
    if (average >= topAverage) {
        if (average > topAverage) {
            topStudents.length = 0; // clear previous content
            topAverage = average;
        }
        topStudents.push(students[i].name);
    }
}

console.log("Top student(s): " + topStudents + " with an average of " + topAverage);

Comments

0

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]
  }
];

console.log (
  Students.map (
    student => (
      {
        name: student.name,
        average:
          student.marks.reduce ((a, m) => a + m, 0) /
          student.marks.length
      }
    )
  ).sort ((a, b) => b.average - a.average)
);

1 Comment

OP said not to use ES6 syntax.
0

Instead of using loops, I used the built-in array methods, which tend to be much more readable (although they would be a lot more readable if you used ES6 syntax).

I use the Array.prototype.map method to convert the list of marks into the average. In order to find this average, I use Array.prototype.reduce to add up all of the values, and then I divide by the length of the marks array. I then sort the array using Array.prototype.sort.

In order to get the top students, I use Array.prototype.filter in order to select only the students will average marks equal to the top average mark, which since the averages array is sorted, will be averages[0].average.

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]
  }
];

var averages = Students.map(function(student) {
  return {
    name: student.name,
    average: student.marks.reduce(function(a, b) {
      return a + b;
    }) / student.marks.length
  };
}).sort(function(a, b) {
  return b.average - a.average;
});

var top_students = averages.filter(function(student, _i, arr) {
  return student.average === arr[0].average;
});

console.log("Averages:");
console.log(averages);

console.log("Top Students:\n");
console.log(top_students);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.