问题
I am havin a json with following structure which can go up to n level depth:
[{
name: 'p1',
child:[{
name: 'c1',
child: [{
name: 'gc1',
child: []
},{
name: 'gc2',
child:[]
}]
},{
name: 'c2',
child: [{
name: 'gc1',
child: []
},{
name: 'gc2',
child:[]
}]
},{
name: 'c3',
child: [{
name: 'gc1',
child: []
},{
name: 'gc2',
child:[]
}]
}]},{
name: 'p2',
child:[{
name: 'c1',
child: [{
name: 'gc1',
child: []
},{
name: 'gc2',
child:[]
}]
},{
name: 'c2',
child: [{
name: 'gc1',
child: []
},{
name: 'gc2',
child:[]
}]
}]}]
Case 1: if search term is c1, the output is
[{
name: 'p1',
child:[{
name: 'c1',
child: []
}]
},{
name: 'p2',
child:[{
name: 'c1',
child: []
}]
}]
Case 2: if user searches for c3, the output is
[{
name: 'p1',
child:[{
name: 'c3',
child: []
}]
}]
Case 3: if user searches for p1, the output is
[{
name: 'p1',
child:[]
}]
Case 4 If user searches for gc1, the output is
[{name: 'p1',child:[{
name: 'c1',
child: [{
name: 'gc1',
child: []
}]},{
name: 'c2',
child: [{
name: 'gc1',
child: []
}]},{
name: 'c3',
child: [{
name: 'gc1',
child: []
}]}]},{name: 'p2', child:[{
name: 'c1',
child: [{
name: 'gc1',
child: []
}]},{
name: 'c2',
child: [{
name: 'gc1',
child: []
}]}]}]
Notice that if children name doesn't match, then it is not included in the output.
I am using the following logic but it doesn't filter nodes 'n' level:
function filterTree(data, matcher) {
data.child= data.child.filter(row => row.name === matcher);
for (nodeIndex in data.child)
filterTree(data.child[nodeIndex], matcher);
}
I need an optimal way to perform filter
回答1:
You could reduce the arrays and look for the wanted name or loock for the child
array and if an object is found add the actual object with the new child array.
function search(array, name) {
const s = (r, { child, ...object }) => {
if (object.name === name) {
r.push({ object, child: [] });
return r;
}
child = child.reduce(s, []);
if (child.length) r.push({ ...object, child });
return r;
};
return array.reduce(s, []);
}
var data = [{ name: 'p1', child: [{ name: 'c1', child: [{ name: 'gc1', child: [] }, { name: 'gc2', child: [] }] }, { name: 'c2', child: [{ name: 'gc1', child: [] }, { name: 'gc2', child: [] }] }, { name: 'c3', child: [{ name: 'gc1', child: [] }, { name: 'gc2', child: [] }] }] }, { name: 'p2', child: [{ name: 'c1', child: [{ name: 'gc1', child: [] }, { name: 'gc2', child: [] }] }, { name: 'c2', child: [{ name: 'gc1', child: [] }, { name: 'gc2', child: [] }] }] }];
console.log(search(data, 'c1'));
console.log(search(data, 'c3'));
console.log(search(data, 'p1'));
console.log(search(data, 'gc1'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
来源:https://stackoverflow.com/questions/62611107/a-javascript-function-to-filter-tree-structured-json-with-a-search-term-exclude