访问jSON文件中的子树

时间:2018-05-16 10:19:19

标签: javascript arrays json

大家好,我希望你能帮我解决这个问题。我的JSON文件的结构如下:

[{
   {
    "link": {
       "title": "Applications"
    },
    "has_children": true,
    "subtree": [{
        "link": {
        "title": "Projects"
       },
       "subtree": [{
          "link": {
             "title": "WORK\/NEW YORK",
          }
       }]
     }]
   }
}]

基本上它是一个导航菜单,它应该是这样的:

  

应用程序=> Projects =>工作/纽约

我正在遍历整个JSON文件以获取所有第一个对象。我已设法访问第一个对象并使用以下代码显示“Application”:

for (var i = 0; i < list.length; i++) {            
    var _title = (list[i].link.title);
    console.log(_title);     
    buildingMenuContent(_title);
}

现在,我想迭代第一个数组索引[0]并访问其子树第一个索引[0],最后访问最后一个子树及其索引[0],以便我能够显示:

  

应用程序=&gt; Projects =&gt;工作/纽约

我使用了这个代码,让我接受了应用程序=&gt;项目,但它没有迭代来获得所有第一个对象:

 for (var i = 0; i < list.length; i++) {
         if (list[i].has_children) {
            for (var n = 0; n < list[i].subtree.length; n++) {
            var _subtitle = (list[i].subtree[n].link.title);
         }
       }    
    } 
 }

我不知道我是否澄清了这一点,但我需要循环通过这个数组。我使用了递归for循环,但是在使用它之后操作DOM太复杂了。

2 个答案:

答案 0 :(得分:0)

首先你输入错了!!!语法错误, 第二次递归是唯一的方法,因为你不知道你必须下台的水平

var q =[
 {
    "link": {
        "title": "Applications"
            },
    "has_children": true,
    "subtree": [{
            "link": {
                "title": "Projects"
            },
            "subtree": [{
                    "link": {
                        "title": "WORK\/NEW YORK",
                            }}]
                     }]
  }]


function find_child(json)
//a function move down until error happen (last level of json)
  {
      result ="" // this varible hold result
    try // just to avoid if!!! at last level of json it will go to catch and end this loop
    {
        if(json.link.title) // check this field is in json ?
            result += json.link.title
        result += "=>" +find_child( json.subtree[0]) /* call again with {
        "link": {
            "title": "Projects"
        },
        "subtree": [{
                "link": {
                    "title": "WORK\/NEW YORK",
                        }}]
                 } and second type with nex child at forth time it cause error and return*/

    }
    catch (e)
    {
    }
    return result
  }

  print(find_child(q[0],""))

result = Applications =&gt; Projects =&gt; WORK / NEW YORK

答案 1 :(得分:0)

let tree = {}; //your parsed JSON here

const loopTree = (tree, subTreePropName, resultAccumulator) => {
  if (tree) {
    if (tree[subTreePropName]) {
      resultAccumulator += tree[subTreePropName].map((subtree) => loopTree(subtree, subTreePropName, resultAccumulator));
    }
    return resultAccumulator + tree.link.title;
  }
  return '';
}

let result = loopTree(tree, 'subtree', '');

我没有对此进行测试,但它应该有效...解释loopTree的工作原理:

if (tree)检查是否使用未定义的项调用了该函数。如果这是假(或null或未定义 - 意味着使用空对象调用),则返回一个空字符串。否则,让我们循环树!

if (tree[subTreePropName])检查我们正在访问的当前树是否具有子树属性。如果没有,它就是一片叶子。返回resultAccumulator +自己的文本。否则,它是一个分支,让它循环吧!

resultAccumulator += tree[...].map(...)这是递归的核心。它说 - 对于当前树的子树中的每个项目,循环它并将结果添加到我们的结果中。

return resultAccumulator + tree.link.title;是关闭递归的行。它返回当前结果+自己的标题。

let result = loopTree(tree, 'subtree', '')是我们有效执行循环的地方。我们说,循环树tree,在名为'subtreee'的属性中查找子项,并将每个项的结果添加到空字符串中。最终结果设置为结果变量。

这有意义吗? 这是你需要的,还是我错过了某些条件?

如果您想更进一步,可以在函数中传递一个额外的processValues值来映射特定的树项...... EX:

let processValues = (treeItem) => {
  return treeItem.link.title
}

然后

let tree = {}; //your parsed JSON here

const loopTree = (tree, subTreePropName, resultAccumulator, itemMapper) => {
  if (tree) {
    if (tree[subTreePropName]) {
      resultAccumulator += tree[subTreePropName].map((subtree) => loopTree(subtree, subTreePropName, resultAccumulator, itemMapper));
    }
    return resultAccumulator + itemMapper(tree);
  }
  return '';
}

let result = loopTree(tree, 'subtree', '', processValues);

这将允许将函数作为第4个参数传递。此函数应接收树项,并返回其相关值。

通过这种方式,您可以在该processValues函数中添加所有条件和操作,并且循环保持干净。