2014-02-13 78 views
2

我正在尝试为节点中存储在MongoDB中的页面生成URL。在树中遍历javascript

使用下面的函数我想遍历一个javascript对象并显示每个元素的路径。

我快要到了,但我被卡住了 - 甚至可能有更好的方法来使用异步(我必须承认,让我有点困惑)做到这一点。

功能:(demo

function printTree(people, slug) { 
    for (var p = 0; p < people.length; p++) { 
     var root = people[p]; 
     slug = slug + root.name + "/"; 
     console.log(slug); 
     if (root.children.length > 0) { 
      var childrenCount = root.children.length; 
      for (var c = 0; c < childrenCount; c++) { 
       if (root.children[c].children.length > 0) { 
        printTree(root.children[c].children, slug + root.children[c].name + "/"); 
       } 
      } 
     } 
    } 
}; 

输出:

/michael/ 
/michael/angela/oscar 
/michael/meredith/creed 
/michael/meredith/creed/kelly 

预期输出:

/michael/ 
/michael/angela/ 
/michael/angela/oscar/ 
/michael/meredith/ 
/michael/meredith/creed/ 
/michael/meredith/kelly/ 

对象:

[ 
    { 
    "name": "michael", 
    ... 
    "children": [ 
     { 
     "name": "angela", 
     ... 
     "children": [ 
      { 
      "name": "oscar", 
      ... 
      "children": [] 
      } 
     ] 
     }, 
     { 
     "name": "meredith", 
     ... 
     "children": [ 
      { 
      "name": "creed", 
      ... 
      "children": [] 
      }, 
      { 
      "name": "kelly", 
      ... 
      "children": [] 
      } 
     ] 
     }, 
     { ... } 
    ] 
    } 
] 

如果有帮助,数据使用嵌套集的存储:https://github.com/groupdock/mongoose-nested-set 所以有可能是一个更好的办法做到使用嵌套组(否定了上述目的)以上工作。

回答

5

你在这里。您不需要第二个for循环,因为您的printTree函数将循环所有内容(demo)。

function printTree(people, slug){ 
    slug = slug || '/'; 
    for(var i = 0; i < people.length; i++) { 
    console.log(slug + people[i].name + '/'); 
    if(people[i].children.length){ 
     printTree(people[i].children, slug + people[i].name + '/') 
    } 
    } 
} 
+0

你绝对钉它! http://jsfiddle.net/cT8wn/2/ –

+0

嗨,这适用于迈克尔,安吉拉和奥斯卡,但是一旦树到达迈克尔的其他孩子,它就会破裂。 [见demo](http://jsfiddle.net/WHZUE/)meredith是angela的兄弟姐妹,但输出显示meredith是angela的孩子。 – logikal

+0

这是因为这一行:'slug = slug + people [i] .name +'/';'为你解决 –

1

你也可以考虑在ECMA5这样的事情,如果你有进一步的使用tree的或者想使用一些比其他/一个分隔符。 @bioball的答案没有错,这只是给你更多的灵活性,如果想要的话。

function makeTree(people, slug, sep) { 
    slug = slug || '/'; 
    sep = sep || slug; 
    return people.reduce(function (tree, person) { 
     var slugPerson = slug + person.name + sep; 

     return tree.concat(slugPerson, makeTree(person.children, slugPerson, sep)); 
    }, []); 
} 

function printTree(tree) { 
    tree.forEach(function (path) { 
     console.log(path); 
    }); 
} 

printTree(makeTree(data)); 

jsFiddle

+0

这是一个不错的解决方案!扭转这种方法为人们创造一条道路会更容易吗? IE:鉴于“凯利”和树,生成/ michael/meredith /凯利?我目前正试图扭转这个梦幻般的@bioball和Jason提供的做法,但我失败了。 – logikal

+0

听起来像是你应该在这里创建的另一个问题,也许你会为一个好问题赚取更多代表。但也许你的意思就像在这[jsFiddle](http://jsfiddle.net/Xotic750/wwDmJ/)?当然你可以改变过滤器来做任何你想做的事情。我已经给出了2个例子。 – Xotic750