2011-03-05 165 views
1

這裏是代碼片斷,這進入了一個無限循環 - 「太多的遞歸錯誤」。Javascript簡單遞歸問題

SW = { 
    WData : { 
     wf : { 

      roots : [852,1517,1523,1540], 
      leaves : [], 
      features : { 
       852: { "cf":"855,1848"}, 
       1517: { "cf":"1929,1930"}, 
       1523: { "cf":""}, 
       1540: { "cf":"1546,1549"}, 
       855: { "cf":"" }, 
       1848: { "cf":""}, 
       1929: { "cf":""}, 
       1930: { "cf":""}, 
       1546: { "cf":"1600"}, 
       1549: { "cf":""}, 
       1600: { "cf":""}     
      } 
     } 
    }, 

    init: function init(){     
     this.buildTree(); 
     //console.log(this.WData.wf.leaves); 
    }, 

    buildTree : function(){ 
     this.getLeaves(this.WData.wf.roots); 
    }, 

    getLeaves: function(roots){ 
     for(var i in roots){ 
      var root = this.WData.wf.roots[i]; 

      if(this.WData.wf.features[ root ].cf === ""){ 

       this.WData.wf.leaves.push(root); 
       return false; 
      } 
      else{ 
       this.getLeaves(this.WData.wf.features[root].cf.split(',').map(Number)); 
      } 
     } 
     return false; 
    } 
} 


SW.init(); 

無法理解此處存在的問題。我有一種感覺,我犯了一個很簡單的錯誤。

http://jsfiddle.net/eWGG8/4/

回答

1

你有幾個問題:

  1. 在循環的開始,您應該使用roots而不是this.WData.wf.roots,例如。像這樣:

    var root = roots[i]; 
    
  2. 您正在試圖推動新的項目到一個字符串,而不是一個數組,這樣在你的結構,改變留給了以下內容:

    leaves : ["asdf"], 
    
  3. 這就導致一個錯誤,當您嘗試將其分配給你的結果DIV(在的jsfiddle),所以使用聯接來創建一個字符串

    $('#result').append(SW.WData.wf.leaves.join(",")); 
    
0

你的終止條件是在這一行:

for(var i in roots){

爲什麼不能像這樣的東西console.log(i)跟進,看看它在做什麼你的想法。這種技術通常比調試器更快。

0

你不斷引用原樹在你的遞歸 - 你可能要拆分,你通過在遞歸的節點上:

getLeaves: function(roots){ 
for(var i in roots){ 
    var root = roots[i]; 

    if(!(root.cf)){ 

     this.WData.wf.leaves.push(root); 
     return false; 
    } 
    else{ 
     this.getLeaves(root.cf.split(',').map(Number)); 
    } 
} 
return false; 
0

從我所知道的情況來看,您需要更改features條目中cf屬性的值,以反映您已經解析了它們。如果不這樣做,你的代碼

else{ 
    this.getLeaves(this.WData.wf.features[root].cf.split(',').map(Number)); 
} 

的這個分支將無限值添加到leavesArray,如果我是正確的。

所以,儘量添加類似:

else { 

    var cf = this.WData.wf.features[root].cf ; // save the current cf value 

    //... change this.WData.wf.features[root].cf to the desired value 

     this.getLeaves(cf.split(',').map(Number)) ; 


} 

順便說一句,Array.map是一個瀏覽器實現特定的功能(Gecko的瀏覽器,如火狐)。換句話說,你的代碼在沒有實現的地方不起作用。

此外,在我看來,你會很好地添加評論和摺疊你的代碼,使其更容易理解。現在寫的方式很簡單,但很難掌握它的基本目的。