Reputation: 107
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)
Upvotes: 2
Views: 611
Reputation: 637
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
Upvotes: 1
Reputation: 690
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);
Upvotes: 0
Reputation: 13890
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)
);
Upvotes: 0
Reputation: 350252
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);
Upvotes: 0
Reputation: 780974
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}`);
Upvotes: 1