2

I have the below nested data array. I would like to filter on the second level of children leaving only the children that have a name of either "Assistant" or "Advisor" while keeping the rest of the underlying data structure the same.

data = [{
  "name": "root",
  "median": 60000.0,
  "children": [{
      "name": "Defence",
      "median": 60000.0,
      "children": [{
          "name": "Assistant",
          "median": 30000.0,
        },
        {
          "name": "Advisor",
          "median": 50000.0,
        },
        {
          "name": "Secretary",
          "median": 60000.0,
        },
        {
          "name": "Administrator",
          "median": 60000.0,
        },
        {
          "name": "Assistant",
          "median": 20000.0,
        },
      ]
    },
    {
      "name": "Healthcare",
      "median": 60000,
      "children": [{
          "name": "Manager",
          "median": 80000,
        },
        {
          "name": "Advisor",
          "median": 60000,
        },
        {
          "name": "Legal",
          "median": 20000,
        },
        {
          "name": "Cashier",
          "median": 30000,
        },
      ]
    }
  ]
}]

The desired outcome leaves the upper level children the same while returning the second level children that match "Assistant" and "Advisor".

data = [{
  "name": "root",
  "median": 60000.0,
  "children": [{
      "name": "Defence",
      "median": 60000.0,
      "children": [{
          "name": "Assistant",
          "median": 30000.0,
        },
        {
          "name": "Advisor",
          "median": 50000.0,
        },
        {
          "name": "Assistant",
          "median": 20000.0,
        },
      ]
    },
    {
      "name": "Healthcare",
      "median": 60000,
      "children": [{
          "name": "Advisor",
          "median": 60000,
        },
      ]
    }
  ]
}]

I have tried to use a combination of map() and filter() but it only returns the matching second level children.

var fmatch = ["Assistant", "Advisor"]
console.log(data.map(c=> c.children.map(c => c.children.filter(c => fmatch.includes(c.name)))))

data = data = [{
  "name": "root",
  "median": 60000.0,
  "children": [{
      "name": "Defence",
      "median": 60000.0,
      "children": [{
          "name": "Assistant",
          "median": 30000.0,
        },
        {
          "name": "Advisor",
          "median": 50000.0,
        },
        {
          "name": "Secretary",
          "median": 60000.0,
        },
        {
          "name": "Administrator",
          "median": 60000.0,
        },
        {
          "name": "Assistant",
          "median": 20000.0,
        },
      ]
    },
    {
      "name": "Healthcare",
      "median": 60000,
      "children": [{
          "name": "Manager",
          "median": 80000,
        },
        {
          "name": "Advisor",
          "median": 60000,
        },
        {
          "name": "Legal",
          "median": 20000,
        },
        {
          "name": "Cashier",
          "median": 30000,
        },
      ]
    }
  ]
}]

var fmatch = ["Assistant", "Advisor"]
console.log(data.map(c=> c.children.map(c => c.children.filter(c => fmatch.includes(c.name)))))

2 Answers 2

1

You can just use a simple loop to iterate each parent and only use filter when needed.

If you still want to use .map() you would need to return the full objects instead of the filtered array only

data = [{
  "name": "root",
  "median": 60000.0,
  "children": [{
      "name": "Defence",
      "median": 60000.0,
      "children": [{
          "name": "Assistant",
          "median": 30000.0,
        },
        {
          "name": "Advisor",
          "median": 50000.0,
        },
        {
          "name": "Secretary",
          "median": 60000.0,
        },
        {
          "name": "Administrator",
          "median": 60000.0,
        },
        {
          "name": "Assistant",
          "median": 20000.0,
        },
      ]
    },
    {
      "name": "Healthcare",
      "median": 60000,
      "children": [{
          "name": "Manager",
          "median": 80000,
        },
        {
          "name": "Advisor",
          "median": 60000,
        },
        {
          "name": "Legal",
          "median": 20000,
        },
        {
          "name": "Cashier",
          "median": 30000,
        },
      ]
    }
  ]
}]

var fmatch = ["Assistant", "Advisor"];

const filteredData = data;
filteredData.forEach(item => {
  item.children.forEach(firstChild => {
    firstChild.children = firstChild.children.filter(c => fmatch.includes(c.name));
  });
});

console.log(filteredData);

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

Comments

0

You need to use a forEach loop when you're looking to modify the underlying data structure. All Array.prototype.map() does is return a new array based on the criteria provided.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

data = data = [{
  "name": "root",
  "median": 60000.0,
  "children": [{
      "name": "Defence",
      "median": 60000.0,
      "children": [{
          "name": "Assistant",
          "median": 30000.0,
        },
        {
          "name": "Advisor",
          "median": 50000.0,
        },
        {
          "name": "Secretary",
          "median": 60000.0,
        },
        {
          "name": "Administrator",
          "median": 60000.0,
        },
        {
          "name": "Assistant",
          "median": 20000.0,
        },
      ]
    },
    {
      "name": "Healthcare",
      "median": 60000,
      "children": [{
          "name": "Manager",
          "median": 80000,
        },
        {
          "name": "Advisor",
          "median": 60000,
        },
        {
          "name": "Legal",
          "median": 20000,
        },
        {
          "name": "Cashier",
          "median": 30000,
        },
      ]
    }
  ]
}]

var fmatch = ["Assistant", "Advisor"]
data.forEach(c => {
    c.children.forEach(c => {
        c.children = c.children.filter(c => fmatch.includes(c.name))
    })
})
console.log(data)

Comments

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.