I'm a bit skeptical of the average calculation for student B in the 2nd array...
Upon reviewing my code, I arrived at an average of 52.5 instead.
let profile = [
{student: "A", english: 80, maths: 80},
{student: "B", english: 50, maths: 50},
{student: "A", english: 70, maths: 60},
{student: "B", english: "--", maths: 60}
]
//sort by student
profile.sort((a, b) => a.student.localeCompare(b.student));
const studentsCount = profile.reduce((pre, cur, index) => {
let find = profile.findIndex((e, _index) => _index > index && e.student === cur.student);
if (find == -1) {
return pre + 1;
} else return pre;
}, 0);
//stage 1
let curProfile = profile[0], startIndex, endIndex, _profile = [], maths = 0, english = 0, noScoreMaths, noScoreEnglish;
for (let i = 0; i < studentsCount; i++) {
startIndex = profile.findIndex(p => p.student === curProfile.student);
endIndex = profile.findLastIndex(p => p.student === curProfile.student);
noScoreMaths = 0, noScoreEnglish = 0;
for (let j = startIndex; j <= endIndex; j++) {
if (isNaN(parseInt(profile[j].maths))) noScoreMaths++;
if (isNaN(parseInt(profile[j].english))) noScoreEnglish++;
maths += isNaN(parseInt(profile[j].maths)) ? 0 : profile[j].maths;
english += isNaN(parseInt(profile[j].english)) ? 0 : profile[j].english;
if (j === endIndex) {
maths = parseFloat((maths / (endIndex - startIndex + 1 - noScoreMaths)).toFixed(1));
english = parseFloat((english / (endIndex - startIndex + 1 - noScoreEnglish)).toFixed(1));
_profile.push({
student: curProfile.student,
maths,
english
});
curProfile = profile[j + 1];
maths = 0;
english = 0;
noScoreMaths = 0;
noScoreEnglish = 0;
}
}
}
//stage 2
let __profile = [];
for (let i = 0; i < _profile.length; i++) {
let avgScore = parseFloat(((_profile[i].maths + _profile[i].english) / 2).toFixed(1));
__profile.push({ student: _profile[i].student, average: avgScore });
}
console.log(_profile);
console.log(__profile);