大家好,我希望你能帮我解决这个问题。我的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太复杂了。
答案 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函数中添加所有条件和操作,并且循环保持干净。