Reputation: 1535
I am looking to find elegant solution to filter nested json data structure so that filter functionality can be applied.
pre-condtions:
Y
and by Z
than
results of Y and Z should be shown in Tree Structure. But currently displayed example below
for filter by kind
property and value to filter applied is Y
.Thanks!!
e.g
var dataToFilter = {
"children": [{
"tagPath": "/../../tagPath-1",
"children": [{
"tagPath": "/../../tagPath-1-1",
"children": [{
"tagPath": "/../../tagPath-1-2",
"kind": "Y",
"children": [{
"tagPath": "/../../tagPath-1-3.1",
"kind": "X",
"children": []
},
{
"tagPath": "/../../tagPath-1.3.2",
"kind": "X",
"children": [{
"tagPath": "/../../tagPath-1.3",
"kind": "Y",
"children": []
}]
}
]
},
{
"kind": "Y",
"children": []
}
],
"kind": "X",
}],
"kind": "Y",
}]
Desired Output on kind
property when value is e.g Y
:
var desiredOutput = {
"children": [{
"tagPath": "/../../tagPath-1",
"children": [{
"tagPath": "/../../tagPath-1-2",
"kind": "Y",
"children": [{
"tagPath": "/../../tagPath-1.3",
"kind": "Y",
"children": []
}]
},
{
"kind": "Y",
"children": []
}
],
"kind": "Y",
}]
```
Upvotes: 1
Views: 518
Reputation: 54649
You can use the following function:
const restructure = (nodes, filter) => nodes.reduce(
(acc, node) => {
const children = restructure(node.children, filter);
return acc.concat(
filter(node)
? {...node, children}
: children
);
},
[]
);
Which accepts filter
as a function. This allows you to decide how to filter, e.g.:
const yOnly = restructure(dataToFilter, node => 'Y' === node.kind);
Or:
const yAndX = restructure(dataToFilter, node => ['Y', 'X'].includes(node.kind));
The only difference to your code above is that dataToFilter
must already be an array of nodes (see the full code snippet below).
const restructure = (nodes, filter) => nodes.reduce(
(acc, node) => {
const children = restructure(node.children, filter);
return acc.concat(
filter(node)
? {...node, children}
: children
);
},
[]
);
const dataToFilter = [{
'tagPath': '/../../tagPath-1',
'children': [{
'tagPath': '/../../tagPath-1-1',
'children': [{
'tagPath': '/../../tagPath-1-2',
'kind': 'Y',
'children': [{
'tagPath': '/../../tagPath-1-3.1',
'kind': 'X',
'children': []
}, {
'tagPath': '/../../tagPath-1.3.2',
'kind': 'X',
'children': [{
'tagPath': '/../../tagPath-1.3',
'kind': 'Y',
'children': []
}]
}]
}, {
'kind': 'Y',
'children': []
}],
'kind': 'X',
}],
'kind': 'Y',
}];
const yOnly = restructure(dataToFilter, node => 'Y' === node.kind);
const xOnly = restructure(dataToFilter, node => 'X' === node.kind);
const yAndX = restructure(dataToFilter, node => ['Y', 'X'].includes(node.kind));
console.log(yOnly);
console.log(xOnly);
console.log(yAndX);
Upvotes: 1