【问题标题】:Improve loop over nested properties - javascript改进嵌套属性的循环 - javascript
【发布时间】:2019-05-24 14:25:43
【问题描述】:

尝试根据嵌套属性值过滤学生。 基本上每个学生对象都有数组类型的属性:studentSuperSubject 它又具有数组作为属性:studentSubSubjectOrSkill subjects 是以下形式的对象数组: {superSubject: "some super subject name", subSubject: "some sub subject name"}studentSubSubjectOrSkill 内的每个 subSubject 都有 studentSubSubjectScore 属性,这是我正在寻找的属性。 我想循环遍历 subjects 中每个主题的学生数组并创建和对象我然后存储到另一个数组 - grades=[]

我设法用看起来像是一串意大利面条代码的 Hugh bwl 来完成它:

  for (let subject of subjects) {
    var grades = [];
    this.data.students.filter(student => {
      let name = student.studentName;

      // loop over each student > superSubject > subSubject
      for (let superSubject of student.studentSuperSubject) {
        if (superSubject.superSubjectName === subject.superSubject) {
          superSubject.studentSubSubjectOrSkill.filter(sub => {
            if (sub.subSubjectName === subject.subSubject) {
              grades.push({
                name: name,
                pass: sub.studentSubSubjectScore > 58
              });
              return;
            }
          });
        }
      }
    });
    subject["grades"] = grades;
  }

知道如何改进它以使将来使用此代码的开发人员的生活更轻松吗? 作为旁注,lodash 在这个项目中可用 谢谢。

【问题讨论】:

  • 您已经在学生身上使用了filter,我也会将它用于内部 for 循环。你可以用map 替换外部的for循环

标签: javascript lodash


【解决方案1】:

为了可读性,我会一次检查一件事并添加一些 cmets。

// Iterates for all subjects.
subjects.forEach(subject => {
    // Subject grades.
    subject.grades = [];

    // Iterates for all the students.
    students.forEach(student => {
        // Finds and validates the student super subject.
        var studentSuperSubject = student.studentSuperSubject.find(superSubject => superSubject.superSubjectName === subject.superSubject);
        if (!studentSuperSubject) return;

        // Finds and validates the student sub subject.
        var studentSubSubject = studentSuperSubject.studentSubSubjectOrSkill.find(subSubject => subSubject.subSubjectName == subject.subSubject);
        if (!studentSubSubject) return;

        // Saves the student grade.
        subject.grades.push({
            name: student.studentName,
            pass: studentSubSubject.studentSubSubjectScore > 58
        });
    });
});

【讨论】:

    【解决方案2】:

    1/ 当你想要返回数组的子集时,你应该使用不正确的过滤器,当你想要对数组的每个元素执行一个动作时,你应该使用 map

    2/ for... of ... 用于迭代值,for... in... 在属性上

    3/ 我认为这样更具可读性:

    for (let subject of subjects) {
        var grades = [];
    
        this.data.students.map(student => {
          let name = student.studentName;
    
          student.studentSuperSubject
              .filter(superSubject => superSubject.superSubjectName === subject.superSubject)
              .map(superSubject=> {                     
                  superSubject.studentSubSubjectOrSkill
                      .filter(sub => sub.subSubjectName === subject.subSubject)
                      .map(sub=>{
                          grades.push({
                              name: name,
                              pass: sub.studentSubSubjectScore > 58
                          });
                      });
              });
          });
    
       subject["grades"] = grades;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-25
      • 2018-05-06
      • 2018-03-19
      • 1970-01-01
      • 2014-04-19
      • 1970-01-01
      相关资源
      最近更新 更多