【问题标题】:Filter nested object and keep parents过滤嵌套对象并保留父对象
【发布时间】:2019-09-12 18:54:37
【问题描述】:

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

例如,

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

如果我搜索“玛丽”,它应该是返回:

[
    {
        name: 'Mary',
    }
]

如果我搜索“Jack”,它应该是返回:

[
    {
        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);
})

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

【问题讨论】:

  • 深度优先搜索算法?
  • 同一血统中有多个同名的人怎么办?例如,在 Lisa 的案例中,如果将“Mary”替换为“Lisa”会怎样?
  • @JonathanHamel 感谢您指出它被称为深度优先搜索!我学到了很多。
  • @kingkupps 我也很好奇。在您的示例中,这些解决方案将失败。

标签: javascript object filter nested


【解决方案1】:

您可以构建一个对象,如果嵌套,则检查子对象并在必要时创建父对象。

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,而且速度惊人
  • 感谢您的出色解决方案!
【解决方案2】:

以下是深度优先方法的示例:

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'));

【讨论】:

  • 您的解决方案很有帮助。非常感谢!
猜你喜欢
  • 2021-06-09
  • 2022-01-21
  • 1970-01-01
  • 2017-03-08
  • 2020-07-28
  • 2020-03-11
相关资源
最近更新 更多