I've been struggling with one task I've been doing for learning purposes. I have an object with a few stundents inside and I want to calculate average marks of Steven.
Example:
const students = [
{
name: 'John',
surname: 'Johnson',
faculty: 'Faculty of Science',
modules: [
{
title: 'Operating systems',
marks: [10, 10, 9]
},
{
title: 'Algorythms',
marks: [8, 10, 8]
},
{
title: 'Statistics',
marks: [9, 7, 8]
},
]
},
{
name: 'Steven',
surname: 'Stevenson',
faculty: 'Faculty of Science',
modules: [
{
title: 'Operating systems',
marks: [7, 6, 9]
},
{
title: 'Algorythms',
marks: [7, 8, 9]
},
{
title: 'Statistics',
marks: [6, 8, 10]
},
]
},
];
Using the filter method I was able to filter only Steven from the given object.
const studentSteven = students.filter(student => student.name === 'Steven');
How can I calculate his average mark of all modules? I would like to achieve this using array methods. Any tip would be much appreciated.
Create an array of marks with flatMap.
reduce over that array to create an overall average.
Return an updated object.
const students=[{name:"John",surname:"Johnson",faculty:"Faculty of Science",modules:[{title:"Operating systems",marks:[10,10,9]},{title:"Algorythms",marks:[8,10,8]},{title:"Statistics",marks:[9,7,8]}]},{name:"Steven",surname:"Stevenson",faculty:"Faculty of Science",modules:[{title:"Operating systems",marks:[7,6,9]},{title:"Algorythms",marks:[7,8,9]},{title:"Statistics",marks:[6,8,10]}]}];
const out = students.map(obj => {
// Destructure the modules property from the
// rest of the object properties
const { modules, ...rest } = obj;
// Return each marks array, and then flatten them
const marks = modules.flatMap(obj => obj.marks);
// `reduce` over the marks array to create a overall
// sum, divide it by the number of marks,
// and round up the returned floating-point number
const average = Math.round(marks.reduce((acc, c) => {
return acc + c;
}, 0) / marks.length);
// Return a new updated object
return { ...rest, average, modules };
});
console.log(out);
Additional documentation
const students = [
{
name: 'John',
surname: 'Johnson',
faculty: 'Faculty of Science',
modules: [
{
title: 'Operating systems',
marks: [10, 10, 9]
},
{
title: 'Algorythms',
marks: [8, 10, 8]
},
{
title: 'Statistics',
marks: [9, 7, 8]
},
]
},
{
name: 'Steven',
surname: 'Stevenson',
faculty: 'Faculty of Science',
modules: [
{
title: 'Operating systems',
marks: [7, 6, 9]
},
{
title: 'Algorythms',
marks: [7, 8, 9]
},
{
title: 'Statistics',
marks: [6, 8, 10]
},
]
},
];
var studentSteven = students.filter(student => student.name === 'Steven');
studentSteven = studentSteven[0]
let g = 0;
let sum = 0;
for(i = 0;i < studentSteven.modules.length;i++){
sum += studentSteven.modules[i].marks.reduce((s,t)=>{
g++
return s + t
})
g++
}
avg = sum/g
You can map over the students array and for every student again map over the modules array and add a property called averageMarks to the each module object.
const students = [
{
name: "John",
surname: "Johnson",
faculty: "Faculty of Science",
modules: [
{ title: "Operating systems", marks: [10, 10, 9] },
{ title: "Algorythms", marks: [8, 10, 8] },
{ title: "Statistics", marks: [9, 7, 8] },
],
},
{
name: "Steven",
surname: "Stevenson",
faculty: "Faculty of Science",
modules: [
{ title: "Operating systems", marks: [7, 6, 9] },
{ title: "Algorythms", marks: [7, 8, 9] },
{ title: "Statistics", marks: [6, 8, 10] },
],
},
];
const updatedStudents = students.map((st) => ({
...st,
modules: st.modules.map((mod) => ({
...mod,
averageMarks: mod.marks.reduce((sum, m) => sum + m) / mod.marks.length,
})),
}));
console.log(updatedStudents);
If you also need to calculate the average of all modules, then you can chain the above result with another map and add an average property for each student.
const students = [
{
name: "John",
surname: "Johnson",
faculty: "Faculty of Science",
modules: [
{ title: "Operating systems", marks: [10, 10, 9] },
{ title: "Algorythms", marks: [8, 10, 8] },
{ title: "Statistics", marks: [9, 7, 8] },
],
},
{
name: "Steven",
surname: "Stevenson",
faculty: "Faculty of Science",
modules: [
{ title: "Operating systems", marks: [7, 6, 9] },
{ title: "Algorythms", marks: [7, 8, 9] },
{ title: "Statistics", marks: [6, 8, 10] },
],
},
];
const updatedStudents = students
.map((st) => ({
...st,
modules: st.modules.map((mod) => ({
...mod,
averageMarks: mod.marks.reduce((sum, m) => sum + m) / mod.marks.length,
})),
}))
.map((st) => ({
...st,
average:
st.modules.reduce((sum, { averageMarks }) => sum + averageMarks, 0) /
st.modules.length,
}));
console.log(updatedStudents);