搜索嵌套对象并返回整个路径 [英] Search nested object and return whole path
问题描述
我在下面的JavaScript中具有n个子级,并且想要搜索id,并且如果其中的任何项具有匹配的id,则需要将对象从根返回到匹配的项.
I have below JavaScript with n level children and want to search for id and if any of item from has matching id than need to return object from root to matching item.
我想从根目录返回找到的项目的整个层次结构,直到带有子项的对象为止.
I want to return entire hierarchy of found item from root till object with it's children.
我尝试使用lodash和下划线,但找不到简单的解决方案.
I tried with lodash and underscore and could not find easy solution.
input: {
"children": [{
"name": "Home",
"title": "Home",
"id": "home1",
"children": []
},
{
"name": "BUSINESS AND ROLE SPECIFIC",
"title": "BUSINESS AND ROLE SPECIFIC",
"id": "BAR1",
"children": [{
"name": "Global Businesses",
"title": "Global Businesses",
"id": "GB1",
"children": [{
"name": "Commercial Banking",
"title": "Commercial Banking",
"id": "CB1",
"children": [{
"name": "FLAGSHIP PROGRAMMES",
"title": "FLAGSHIP PROGRAMMES",
"id": "FG1",
"children": []
}]
}]
}]
},
{
"name": "RISK MANAGEMENT",
"title": "RISK MANAGEMENT",
"id": "RM1",
"children": []
}
]
}
Search: {
id: 'FG1'
}
return :{
"name": "BUSINESS AND ROLE SPECIFIC",
"title": "BUSINESS AND ROLE SPECIFIC",
"id": "BAR1",
"children": [{
"name": "Global Businesses",
"title": "Global Businesses",
"id": "GB1",
"children": [{
"name": "Commercial Banking",
"title": "Commercial Banking",
"id": "CB1",
"children": [{
"name": "FLAGSHIP PROGRAMMES",
"title": "FLAGSHIP PROGRAMMES",
"id": "FG1",
"children": [{}]
}]
}]
}]
}
推荐答案
您可以使用此功能:
function findChild(obj, condition) {
if (Object.entries(condition).every( ([k,v]) => obj[k] === v )) {
return obj;
}
for (const child of obj.children || []) {
const found = findChild(child, condition);
// If found, then add this node to the ancestors of the result
if (found) return Object.assign({}, obj, { children: [found] });
}
}
// Sample data
var input = { "children": [{ "name": "Home", "title": "Home", "id": "home1", "children": [] }, { "name": "BUSINESS AND ROLE SPECIFIC", "title": "BUSINESS AND ROLE SPECIFIC", "id": "BAR1", "children": [{ "name": "Global Businesses", "title": "Global Businesses", "id": "GB1", "children": [{ "name": "Commercial Banking", "title": "Commercial Banking", "id": "CB1", "children": [{ "name": "FLAGSHIP PROGRAMMES", "title": "FLAGSHIP PROGRAMMES", "id": "FG1", "children": [] }] }] }] }, { "name": "RISK MANAGEMENT", "title": "RISK MANAGEMENT", "id": "RM1", "children": [] } ]},
search = { id: 'FG1' };
console.log(findChild(input, search));
.as-console-wrapper { max-height: 100% !important; top: 0; }
您也可以将其用于在多个条件下进行搜索,这些条件必须同时为真:
You can use this also for searching with multiple conditions, which must be true at the same time:
search = { "name": "Global Businesses", "title": "Global Businesses" };
...将为您提供具有指定名称和标题的对象.
... would give you the object that has the specified name and title.
您在评论中问:
有没有办法提供编号以不删除输入中给定节点的子代.喜欢,
Is there way to supply number to not remove children for given node in input. like,
const donotRemoveChildNode = 2;
console.log(findChild(input, search, donotRemoveChildNode ));
......如果满足条件,它将不会删除该特定节点的子节点吗?
...so it will not remove that specific node's children if it matches condition?
在这里,如果我们搜索 {id:'FG1'}
并提供 donotRemoveChildNode = 2
,则不会删除商业银行"的第一级子级.
Here, if we search for { id: 'FG1'}
and supply donotRemoveChildNode = 2
, it would not remove the first level children for "Commercial banking".
我会说 donotRemoveChildNode
必须为3,因为在商业银行"的祖先层次结构中有三个级别的 children
数组.节点.值为0表示最顶层 children
属性的第一级子级.
I would say the donotRemoveChildNode
would have to be 3, as there are three levels of children
arrays in the ancestor-hierarchy of the "Commercial banking" node. A value of 0 would show the first level children of the top-most children
property.
以下是额外参数的工作原理——我在数据中添加了一些记录以说明输出中的差异:
Here is how that extra argument would work -- I added some records to the data to illustrate the difference in the output:
function findChild(obj, condition, removeChildNodesBefore = Infinity) {
if (Object.entries(condition).every( ([k,v]) => obj[k] === v )) {
return obj;
}
for (const child of obj.children || []) {
let found = findChild(child, condition, removeChildNodesBefore - 1);
if (found) {
return Object.assign({}, obj, {
children: removeChildNodesBefore <= 0
? obj.children.map( sibling =>
sibling == child ? found
: Object.assign({}, sibling, {children: []})
)
: [found]
});
}
}
}
var input = { "children": [{ "name": "Home", "title": "Home", "id": "home1", "children": [] }, { "name": "BUSINESS AND ROLE SPECIFIC", "title": "BUSINESS AND ROLE SPECIFIC", "id": "BAR1", "children": [{ "name": "Global Businesses", "title": "Global Businesses", "id": "GB1", "children": [{ "name": "test", "title": "test", "id": "xxx", "children": [{ "name": "testDeep", "title": "test", "id": "deep", "children": []}]}, { "name": "Commercial Banking", "title": "Commercial Banking", "id": "CB1", "children": [{ "name": "test", "title": "test", "id": "yyy", "children": []}, { "name": "FLAGSHIP PROGRAMMES", "title": "FLAGSHIP PROGRAMMES", "id": "FG1", "children": [] }] }] }] }, { "name": "RISK MANAGEMENT", "title": "RISK MANAGEMENT", "id": "RM1", "children": [] } ]},
search = { id: 'FG1' }
console.log(findChild(input, search, 3));
.as-console-wrapper { max-height: 100% !important; top: 0; }
这篇关于搜索嵌套对象并返回整个路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!