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)))))
CodePudding user response:
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)
CodePudding user response:
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);