-2

I have a map method in my JSX file that returns grades from MongoDB intro a table column, separated by comma. I would like to add another column where I would calculate average for each row.

This is how it should look:

This is my code:

{studentsGrades
    .filter((a) => Number(a.partial) === Number(semester))
    .map((grade, i) => {
      return (
        <tr key={i}>
          <td className="alignRight">
            <span>{getSubjectName(grade.userSubject)}</span>
          </td>
          <td>{grade.grade}</td>    // returns a value of a grade
          <td>{ 
              "here should be average grade"
          }
          </td>
        </tr>
      );
    })}

EDIT: This is my getSubjectGrades function:

  const getSubjectGrades = async () => {
  const gradesSubject = await axios.post(`/subjectGrade/all`, {
    ids,
  });
  if (isSubscribed) {
    let prevSubjectID = "";
    let prevPartial = 0;
    let gradesSubjectData = [];

    for (var i = 0; i < gradesSubject.data.length; i++) {
      if (
        gradesSubject.data[i].userSubject != prevSubjectID ||
        gradesSubject.data[i].partial != prevPartial
      ) {
        gradesSubjectData.push(gradesSubject.data[i]);
        prevSubjectID = gradesSubject.data[i].userSubject;
        prevPartial = gradesSubject.data[i].partial;
      } else {
        if (prevPartial == gradesSubject.data[i].partial)
          gradesSubjectData[gradesSubjectData.length - 1].grade +=
            "," + gradesSubject.data[i].grade;
      }
    }

    setStudentsGrades(gradesSubjectData);
  }
};
MiRAY
  • 188
  • 2
  • 15
  • what does your data structure look like? – sloont Jun 21 '21 at 21:07
  • 2
    Does this answer your question? [How to compute the sum and average of elements in an array?](https://stackoverflow.com/questions/10359907/how-to-compute-the-sum-and-average-of-elements-in-an-array) – Jim G. Jun 21 '21 at 21:08
  • Also, using index as key will only lead to headaches later, use a unique property of each element instead. – pilchard Jun 21 '21 at 21:08
  • 2
    Try: `grade.grade.split(',').reduce((a, c, i, arr) => {a += c; if (i === arr.length - 1) { a /= arr.length } return a}, 0)` – Titus Jun 21 '21 at 21:15
  • this one almost works. However if i have 5,9,8 it calculates average for 598, not for 5+9+8 – MiRAY Jun 21 '21 at 21:19
  • 1
    Oh, my bad, `grade.grade.split(',')` will create an array of strings, you'll have to convert the values to numbers first, try: `grade.grade.split(',').map(v => Number(v)).reduce((a, c, i, arr) => {a += c; if (i === arr.length - 1) { a /= arr.length } return a}, 0)` – Titus Jun 21 '21 at 21:32
  • thank you very much, now it works. You should submit this as an answer so i could check it as right answer – MiRAY Jun 21 '21 at 21:33
  • I've posted an answer. By the way, this is unrelated, that subject, is it supposed to be `Matematicã` ? Is it in Romanian or some other latin based language ? – Titus Jun 21 '21 at 21:42
  • yes, it is romanian – MiRAY Jun 21 '21 at 21:43
  • 1
    Cool, I'm Romanian. Salutare, si succes cu aplicatia. – Titus Jun 21 '21 at 21:44

1 Answers1

1

It seems that grade.grade is a string of comma delimited numbers, if that is the case, you could convert it to an array of numbers using something like this: grade.grade.split(',').map(v => Number(v)) and then calculate the average using something like this: .reduce((a, c, i, arr) => ((a += c), ((i === arr.length - 1) ? (a /= arr.length) : a)));

Here is a complete example:

<td>{ grade.grade.split(',').map(v => Number(v)).reduce((a, c, i, arr) => ((a += c), ((i === arr.length - 1) ? (a /= arr.length) : a))) }</td>
Titus
  • 22,031
  • 1
  • 23
  • 33