处理JSON以创建子级与父级的层次关系

时间:2018-06-19 12:27:30

标签: javascript json angular algorithm

我在这里得到了类似的答案,但是我正在寻找与此相反的东西,所以我从这个答案中寻求帮助来解释我的问题: Process JSON to create the hierarchical relationship

所以,我有一个类似这样的原始数据:

{
  "my_data": [
      {
          "name": "bugs_db",
          "type": "database",
          "children": [
              {
                  "name": "oss",
                  "type": "ui"
              },
              {
                  "name": "dashboard",
                  "type": "ui"
              },
              {
                  "name": "dev-dash",
                  "type": "ui"
              }
          ]
      },
      {
          "name": "oss",
          "type": "ui",
          "children": [
              {
                  "name": "active-directory",
                  "type": "nfs"
              },
              {
                  "name": "passive-directory",
                  "type": "FAT32"
              },
              {
                "name": "jira_db",
                "kind": "database"
              }
          ]
      },
      {
          "name": "jira_db",
          "type": "database",
          "children": [
            {
              "name": "oss",
              "kind": "ui"
            },
            {
              "name": "something",
              "kind": "ui"
            }
          ]
      },
      {
          "name": "active_directory",
          "type": "nfs",
          "children": []
      }
  ]
}

我需要处理以上数据以列出一个孩子的所有父母。例如,如果我选择“名称” =“ oss”,则层次关系应如下所示:

{
  "name": "oss",
   "type": "ui",
   "parents": [
     {
        "name": "bugs_db",
        "type": "database",
        "parents": [
        ]
     },
     {
       "name": "jira_db",
       "type": "database"
     }
   ]
}

也可以存在一些循环关系。 bugs_db的oss子代和bugs_db的oss ..的子代。在这种情况下,只需略过一步,然后将键“ circular”添加到父对象即可。我想我可以尝试使用for循环进行处理并实现这一目标。.但是我正在寻找一些建议的类似解决方案:https://stackoverflow.com/a/50491255

2 个答案:

答案 0 :(得分:2)

基本上,您可以使用测试循环引用并过滤父级的相同方案。

function getParents(name, visited = new Set) {
    var item = map.get(name);

    if (!item) {
        return item;
    }

    if (visited.has(name)) {
        return { name, type: item.type, circular: true };
    }

    visited.add(name);

    return {
        name,
        type: item.type,
        parent: object.my_data
            .filter(({ children }) => children.some(o => o.name === name))
            .map(({ name }) => getParents(name, visited))
    };
}

var object = { my_data: [{ name: "bugs_db", type: "database", children: [{ name: "oss", type: "ui" }, { name: "dashboard", type: "ui" }, { name: "dev-dash", type: "ui" }] }, { name: "oss", type: "ui", children: [{ name: "active-directory", type: "nfs" }, { name: "passive-directory", type: "FAT32" }, { name: "jira_db", kind: "database" }] }, { name: "jira_db", type: "database", children: [{ name: "oss", kind: "ui" }, { name: "something", kind: "ui" }] }, { name: "active_directory", type: "nfs", children: [] }] },
    map = new Map(object.my_data.map(o => [o.name, o]));

console.log(getParents("oss"));
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)

我认为可以使用循环以可接受的复杂度解决此问题,就像我在示例中看到的那样,这里有一个非常简单的解决方案:

function childToParent(obj, child){ 

var newObj = {"name": "","type": "","parents":[]};

  obj.my_data.map((o1,i1)=>{
      o1.children.map((o2,i2)=>{
          if(o2.name == child){            
            newObj.name = o2.name;
            if(o2.type) newObj.type = o2.type;
            newObj.parents.push({"name":o1.name, "type":o1.type});
            if(o1.children) newObj.parents[i2]['parents'] =  o1.children;
          }
      });
  });

  return newObj;

}

console.log(childToParent(obj, "oss"));