【问题标题】:Filter nested array based on its nested values根据嵌套值过滤嵌套数组
【发布时间】:2018-10-09 08:35:47
【问题描述】:

如果我有以下数据,我将如何使用 ES6 语法过滤每个 node 中的 students 数组,因此它只返回在 subjects 中具有特定值的学生(例如,subject = '英文')?

数据:

[
  {
    "node": {
      "name": "Miss Jones",
      "students": [
        {
          "name": "John",
          "subjects": ["English", "Maths"]
        },
        {
          "name": "Sarah",
          "subjects": ["Geography"]
        }
      ]
    }
  },
  {
    "node": {
      "name": "Mr Hudson",
      "students": [
        {
          "name": "Joe",
          "subjects": ["Maths", "French"]
        },
        {
          "name": "Samantha",
          "subjects": ["English"]
        }
      ]
    }
  }
]

预期输出:

[
  {
    "node": {
      "name": "Miss Jones",
      "students": [
        {
          "name": "John",
          "subjects": ["English", "Maths"]
        }
      ]
    }
  },
  {
    "node": {
      "name": "Mr Hudson",
      "students": [
        {
          "name": "Samantha",
          "subjects": ["English"]
        }
      ]
    }
  }
]

谢谢!

【问题讨论】:

    标签: javascript ecmascript-6 filtering


    【解决方案1】:

    您不需要函数 map 就像其他答案所暗示的那样,即使处理程序正在改变原始数组。

    只需使用函数forEach 进行循环,使用函数filter 以及函数includes 来检查数组subjects

    const arr = [  {    "node": {      "name": "Miss Jones",      "students": [        {          "name": "John",          "subjects": ["English", "Maths"]        },        {          "name": "Sarah",          "subjects": ["Geography"]        }      ]    }  },  {    "node": {      "name": "Mr Hudson",      "students": [        {          "name": "Joe",          "subjects": ["Maths", "French"]        },        {          "name": "Samantha",          "subjects": ["English"]        }      ]    }  }],
          subject = 'English';
      
    arr.forEach(o => o.node.students = o.node.students.filter(s => s.subjects.includes(subject)));
    
    console.log(arr);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案2】:

      是的,您可以使用 mapfilter

      let nodes = [
        {
          "node": {
            "name": "Miss Jones",
            "students": [
              {
                "name": "John",
                "subjects": ["English", "Maths"]
              },
              {
                "name": "Sarah",
                "subjects": ["Geography"]
              }
            ]
          }
        },
        {
          "node": {
            "name": "Mr Hudson",
            "students": [
              {
                "name": "Joe",
                "subjects": ["Maths", "French"]
              },
              {
                "name": "Samantha",
                "subjects": ["English"]
              }
            ]
          }
        }
      ];
      
      const englishNodes = nodes.map(n => {
        n.node.students = n.node.students.filter(s => s.subjects.includes('English'));
        return n;
      });
      
      console.log(englishNodes);

      【讨论】:

      • 这对于没有英语科目的学生来说是不正确的。它将返回一个包含空学生的节点。请看我的回答
      • 是的,我假设每个节点至少有一名学生以英语为科目。如果没有,您始终可以再次在顶级数组上运行过滤器,以仅选择具有非空学生数组的那些节点。
      • 功能图绝对没用!
      • @Ele 如果您想进一步过滤 nodes 以仅包括那些有非空学生的学生:D
      • @slider function map 用于转换而不是过滤对象。
      【解决方案3】:

      我会使用.map.filter 过滤数据。

      const data = [{ "node": { "name": "Miss Jones", "students": [{ "name": "John", "subjects": ["English", "Maths"] }, { "name": "Sarah", "subjects": ["Geography"] }] } }, { "node": { "name": "Mr Hudson", "students": [{ "name": "Joe", "subjects": ["Maths", "French"] }, { "name": "Samantha", "subjects": ["English"] }] } }];
      
      const results = data.map(({ node }) => {
          const students = node.students.filter(student =>
              student.subjects.includes('English'));
          return {
              node: {
                  ...node,
                  students
              }
          };
      });
      
      console.log(results);

      【讨论】:

      • 这对于没有英语的学生来说是不正确的。它将返回一个包含空学生的节点。请看我的回答
      • 是的,它会返回一个空的学生数组,这是必需的,他只想要英语科目的学生。
      • 功能图绝对没用!
      • 现在我没有改变原始数组。这样更好吗
      【解决方案4】:

      您要做的是转换数据,而不仅仅是过滤。请尝试以下方法:

      data.map((o) => {
        o.students = o.node.students.filter((s) => s.subjects.indexOf("English") >= 0);
        if (o.students.length >= 0) return o;
        return null;
      }).filter((o) => o);
      

      你必须为没有English主题的学生返回null,然后过滤null以忽略它们

      【讨论】:

      • 功能图绝对没用!
      • @Ele 为什么没用?
      猜你喜欢
      • 2018-11-06
      • 2023-02-11
      • 2020-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多