A Javascript function to filter tree structured json with a search term. exclude any object which donot match the search term

醉酒当歌 提交于 2021-01-29 02:20:27

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!