0

If I had the following data, how would I go about filtering the students array in each node using ES6 syntax, so it only returns students that have a particular value in subjects (eg. subject = 'English')?

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"]
        }
      ]
    }
  }
]

Expected output:

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

Thanks!

0

4 Answers 4

1

You don't need the function map like other answers are suggesting, even when the handler is mutating the original array.

Just use the function forEach for looping and the function filter along with the function includes for checking the array 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; }

Sign up to request clarification or add additional context in comments.

Comments

1

Yes, you can do it with map and filter.

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);

6 Comments

This would not correct for case students don't have English subject. It will return a node with empty students. Please see my answer
Yes, I'm assuming every node has at least one student with English as a subject. If not you can always run filter on the top level array again to select only those nodes with a non empty students array.
Function map is definitely useless!
@Ele not if you want to filter nodes further to include only those that have non empty students :D
@slider function map is for conversion rather than filtering objects.
|
1

I would filter the data using .map and .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 Comments

This would not correct for case students don't have English. It will return a node with empty students. Please see my answer
Yes it will return an empty student array and that is the required, he only want the students with English subject.
Function map is definitely useless!
Now i am not mutating the original array. Is this better
0

What are you trying to do is transforming data, not only filter. Please try the following:

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);

You have to return null for students that does not have English subject, then filter null to ignore them

2 Comments

Function map is definitely useless!
@Ele Why it is useless?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.