如何使用函数式编程重构javascript代码

问题描述 投票:0回答:1

我正在尝试使用JavaScript从教科书中学习函数式编程。我必须使用函数式编程来重构一些代码并且很难。如何使用map()filter()reduce()重新编写此代码。

我必须以更实用的方式重写以下代码。我试过,但我不断得到空数组。

const students = [{
    name: "Anna",
    sex: "f",
    grades: [4.5, 3.5, 4]
  },
  {
    name: "Dennis",
    sex: "m",
    country: "Germany",
    grades: [5, 1.5, 4]
  },
  {
    name: "Martha",
    sex: "f",
    grades: [5, 4, 2.5, 3]
  },
  {
    name: "Brock",
    sex: "m",
    grades: [4, 3, 2]
  }
];

// Compute female student results
const femaleStudentsResults = [];
for (const student of students) {
  if (student.sex === "f") {
    let gradesSum = 0;
    for (const grade of student.grades) {
      gradesSum += grade;
    }
    const averageGrade = gradesSum / student.grades.length;
    femaleStudentsResults.push({
      name: student.name,
      avgGrade: averageGrade
    });
  }
}

console.log(femaleStudentsResults);

结果必须与此相同:

[Object{avgGrade: 4, name: 'Anna'}, Object{avgGrade: 3.625, name: 'Martha'}]

我开始将所有的女学生分开

const females = students.filter(gender => gender.sex === 'f')

然后,返回我所做的成绩数组

const grade = females.map(grade => grade.grades);

但是当我尝试使用reduce()找到成绩的平均值时:

 const grade = females
   .map(grade => grade.grades)
   .reduce((accum,curr)=>accum + curr)

我得到以下结果4.5,3.5,45,4,2.5,3。我如何防止这种情况,只获得每个学生平均成绩的平均值?

javascript functional-programming
1个回答
3
投票

使用filter(以获得女学生),然后使用.map(将学生对象转换为使用avgGrade的对象),而不是:

const students = [{
    name: "Anna",
    sex: "f",
    grades: [4.5, 3.5, 4]
  },
  {
    name: "Dennis",
    sex: "m",
    country: "Germany",
    grades: [5, 1.5, 4]
  },
  {
    name: "Martha",
    sex: "f",
    grades: [5, 4, 2.5, 3]
  },
  {
    name: "Brock",
    sex: "m",
    grades: [4, 3, 2]
  }
];

const sum = (a, b) => a + b;
const femaleStudentsResults = students
  .filter(({ sex }) => sex === 'f')
  .map(({ name, grades }) => ({ name, avgGrade: grades.reduce(sum) / grades.length }));
console.log(femaleStudentsResults);
© www.soinside.com 2019 - 2024. All rights reserved.