2014-02-13 114 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