过滤嵌套对象并保留父母

时间:2019-09-12 18:54:37

标签: javascript object filter nested

我想通过属性'name'的值搜索嵌套对象,结果将保留其所有父项。

例如,

const object = [
    {
        name: 'Mary',
        children: [
            {
                name: 'Jack',
            },
            {
                name: 'Kevin',
                children: [
                    {
                        name: 'Lisa',
                    }
                ]
            }
        ]
    },
    {
        name: 'Gina',
        children: [
            {
                name: 'Jack',
            }
        ]
    }    
]

如果我搜索“玛丽”,则应返回:

[
    {
        name: 'Mary',
    }
]

如果我搜索“杰克”,应该返回:

[
    {
        name: 'Mary',
        children: [
            {
                name: 'Jack',
            }
        ]
    },
    {
        name: 'Gina',
        children: [
            {
                name: 'Jack',
            }
        ]
    }
]

如果我搜索“ Lisa”,则应该返回:

[
    {
        name: 'Mary',
        children: [
            {
                name: 'Jack',
                children: [
                    {
                        name: 'Lisa',
                    }
                ]
            }
        ]
    }
]

我尝试了一些方法,但只能过滤两层。如下:

return object.filter(data => {
    if (data.children) {
        return data.name.includes(keyword) || data.children.find(item => item.name.includes(keyword));
    }

    return data.name.includes(keyword);
})

有人能指出我正确的方向吗?谢谢!

2 个答案:

答案 0 :(得分:2)

您可以构建一个对象,并在嵌套的情况下检查子对象并在必要时创建父对象。

function getObjects(array, target) {
    return array.reduce((r, { name, children = [] }) => {
        if (name === target) {
            r.push({ name });
            return r;
        }
        children = getObjects(children, target);
        if (children.length) {
            r.push({ name, children })
        }
        return r;
    }, []);
}


var data = [{ name: 'Mary', children: [{ name: 'Jack' }, { name: 'Kevin', children: [{ name: 'Lisa' }] }] }, { name: 'Gina', children: [{ name: 'Jack' }] }];

console.log(getObjects(data, 'Mary'));
console.log(getObjects(data, 'Jack'));
console.log(getObjects(data, 'Lisa'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)

这是深度优先方法的一个示例:

function searchWithParents(tree, query) {
    let results = [];
    for (const {name, children} of tree) {
        if (name === query) {
            results.push({name});
        }
        if (children) {
            const subtreeResults = searchWithParents(children, query);
            const mappedResults = subtreeResults.map(child => ({name, children: [child]}))
            results = results.concat(mappedResults);
        }
    }
    return results;
}

console.log(searchWithParents(object, 'Mary'));
console.log(searchWithParents(object, 'Jack'));
console.log(searchWithParents(object, 'Lisa'));