递归json树过滤器

时间:2017-02-07 15:11:48

标签: angularjs json

我使用的是角度1.5.9,我有一个像这样的JSON对象:

var data=[
    {"id":1,"name":"object 1", childs:[

        {"id":51,"name":"object 51", childs:[]},
    ]},
    {"id":2,"name":"object 2", childs:[
        {"id":11,"name":"object 11", childs:[]},
        {"id":12,"name":"object 12", childs:[
            {"id":13,"name":"object 100", childs:[]},
        ]},
    ]},
    {"id":3,"name":"object 3", childs:[]},
    {"id":1,"name":"object 1", childs:[]}
];

我需要过滤这棵树,以便获得所有元素(名称中包含过滤字符串和所有父项的分支或叶子)。 即:过滤" 100"将导致

[
    {"id":2,"name":"object 2", childs:[
        {"id":12,"name":"object 12", childs:[
            {"id":13,"name":"object 100", childs:[]},
        ]},
    ]},
]

然后,这些数据将使用数据本身的ng-repeat在自定义树指令中呈现

我想知道是否有人可以建议一种干净而有效的方法来实现这一目标。我写的所有代码似乎都过于复杂,最终遍历树很多次,以至于必须存在更好的方法。

实际的元代码有点像 *顺序读取主数组中的ech JSON对象 *如果名称匹配添加一个属性(可见:true)并返回到开头设置所有父母'可见:trre *如果childs数组包含某些内容,请重新调用主过滤函数以扫描所有子项

这对于小型数据集来说可能是可以接受的,但是在大型对象上可能效率非常低。

2 个答案:

答案 0 :(得分:0)

你可以为此写一些递归的javascript,例如:

function findObjectAndParents(item, name) {
    if (item.name.split(' ')[1] == name) {
        return true;
    }

    for (var i = 0; i < item.childs.length; i++) {
        if (findObjectAndParents(item.childs[i], name)) {
            return true;
        }
    }

    return false;
}

并像这样使用它:

var searchName = "100";
var filtered = data.filter(function(item) {
    return findObjectAndParents(item, searchName);
});

答案 1 :(得分:0)

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

function search(array, name) {
    const s = (r, { childs, ...object }) => {
        if (object.name.includes(name)) {
            r.push({ object, childs: [] });
            return r;
        }
        childs = childs.reduce(s, []);
        if (childs.length) r.push({ ...object, childs });
        return r;
    };
    return array.reduce(s, []);
}


console.log(JSON.stringify(search(data, '100'),0,2));