繁体   English   中英

如何使用Lodash / JS递归过滤嵌套对象?

[英]How can I use Lodash/JS to recursively filter nested objects?

我有一个数组,其中包含深度未知的对象,像这样

var objects = [{
    id: 1,
    name: 'foo'
}, {
    id: 2,
    name: 'bar',
    childs: [{
        id: 3,
        name: 'baz',
        childs: [{
            id: 4,
            name: 'foobar'
        }]
    }]
}];

我希望能够通过其ID过滤特定的子对象。

目前,我正在使用这个小lodash脚本(从这个问题中引用),但是它仅适用于不深于一层的对象。 因此,搜索id: 1id: 2可以正常工作,而搜索id: 3id: 4将返回undefined。

function deepFilter(obj, search) {
    return _(obj)
        .thru(function(coll) {
            return _.union(coll, _.map(coll, 'children'));
        })
        .flatten()
        .find(search);
}

一点JSfiddle。

您需要递归调用该函数才能定位子对象。 尝试跟随

遍历数组,并为每个对象检查是否找到了id 如果是,则中断并返回结果,否则继续在child搜索(如果存在)。

方法1:遍历树枝

使用这种方法,代码首先遍历第一个元素,直到最后一个孩子,然后遍历第二个元素,最后一个孩子,依此类推。

 var objects = [{id: 1,name: 'foo'}, {id: 2,name: 'bar',childs: [{id: 3,name: 'baz',childs: [{id: 4,name: 'foobar'}]}]}]; function findObject(arr, id) { var result; for (let i = 0 ; i < arr.length; i++) { if(arr[i].id === id) { result = arr[i]; break; } if(arr[i].childs) { result = findObject(arr[i].childs, id); if(result) break; } } return result; } console.log(findObject(objects, 4)); 

方法2:遍历树的深度

使用这种方法,代码首先遍历第一级元素,然后遍历第二级元素,依此类推。

 var objects = [{id: 1,name: 'foo'}, {id: 2,name: 'bar',childs: [{id: 3,name: 'baz',childs: [{id: 4,name: 'foobar'}]}]}]; function findObject(arr, id) { var result; var children = []; for (let i = 0 ; i < arr.length; i++) { if(arr[i].id === id) { result = arr[i]; break; } if(arr[i].childs) { children = [...children, ...arr[i].childs]; } } if(!result && children.length) { result = findObject(children, id); } return result; } console.log(findObject(objects, 4)); 

您可以采取迭代和递归的方法。

 function find(id, array) { var result; array.some(o => o.id === id && (result = o) || (result = find(id, o.children || []))); return result; } var objects = [{ id: 1, name: 'foo' }, { id: 2, name: 'bar', children: [{ id: 3, name: 'baz', children: [{ id: 4, name: 'foobar' }] }] }]; console.log(find(1, objects)); console.log(find(2, objects)); console.log(find(3, objects)); console.log(find(4, objects)); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

您可以像这样递归地进行操作:

function deepFind(arr, search) {
    for(var obj of arr) {
        if(search(obj)) {
            return obj;
        }
        if(obj.childs) {
            var deepResult = deepFind(obj.childs, search);
            if(deepResult) {
                return deepResult;
            }
        }
    }
    return null;
}

然后像这样使用它:

var result = deepFind(objects, function(obj) {
    return obj.id === myId;
});

例:

 function deepFind(arr, search) { for(var obj of arr) { if(search(obj)) { return obj; } if(obj.childs) { var deepResult = deepFind(obj.childs, search); if(deepResult) { return deepResult; } } } return null; } var objects = [{id: 1,name: 'foo'}, {id: 2,name: 'bar',childs: [{id: 3,name: 'baz',childs: [{id: 4,name: 'foobar'}]}]}]; console.log("ID 1:", deepFind(objects, obj => obj.id === 1)); console.log("ID 4:", deepFind(objects, obj => obj.id === 4)); console.log("ID 7:", deepFind(objects, obj => obj.id === 7)); 

您可以使用递归函数并检查孩子

 var objects = [{ id: 1, name: 'foo' }, { id: 2, name: 'bar', childs: [{ id: 3, name: 'baz', childs: [{ id: 4, name: 'foobar' }] }] }]; let tempArray = []; function doRecursiveSearch(obj, id) { obj.forEach(function(item) { console.log(item) if (item.id === id) { tempArray.push(item) } else { if (item.childs && Array.isArray(item.childs)) { console.log(item) doRecursiveSearch(item.childs, id) } } }) } doRecursiveSearch(objects, 4) console.log(tempArray) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM