[SOLVED] How to return the average of values in different objects with the same key value in an array on JS? – Stack Overflow

Issue

This Content is from Stack Overflow. Question asked by helloworldbyeworld

Imagine I have an array:

let profile = [
{student: "A", english: 80, maths: 80},
{student: "A", english: 70, maths: 60},
{student: "B", english: 50, maths: 50},
{student: "B", english: "--", maths: 60},
...
]

I want to get two sets of array regarding the average.

  1. The average scores of each subject of each student (Expected output:)
[{student: "A", english: 75, maths: 70},
{student: "B", english: 50, maths: 55}]
  1. The average scores of every subject of each student (Expected output:)
[{student: "A", average: 72.5},
{student: "B", average: 53.3}]

How can I code it? Thank you very much



Solution

I’m not sure but how did you get the average of student B to be 53.3 on the 2nd array…

Check my code below, i got 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);


This Question was asked in StackOverflow by helloworldbyeworld and Answered by DimensityDU It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?