搜索嵌套对象并返回整个路径 [英] Search nested object and return whole path

查看:57
本文介绍了搜索嵌套对象并返回整个路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在下面的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆