Javascript中简单递归的问题

时间:2011-03-05 08:43:26

标签: javascript recursion

这是代码片段,这会进入无限循环 - “递归错误太多”。

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/

4 个答案:

答案 0 :(得分:1)

你有几个问题:

  1. 在循环开始时,您应该使用roots而不是this.WData.wf.roots,例如。像这样:

    var root = roots[i];
    
  2. 您正在尝试将新项目推送到字符串而不是数组,因此在您的结构中,请更改为以下内容:

    leaves : ["asdf"],
    
  3. 当您尝试将其分配给结果div时(在jsFiddle中),这会导致错误,因此请使用join来创建字符串

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

答案 1 :(得分:0)

你的终止条件在这一行:

for(var i in roots){

所以为什么不跟着这个console.log(i)这样的事情来看看它是否按照你的想法行事。这种技术通常比调试器更快。

答案 2 :(得分: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;

答案 3 :(得分:0)

据我所知,您需要更改cf条目中features属性的值,以反映您已经解析过它们。如果不这样做,那么代码的这个分支

else{
    this.getLeaves( this.WData.wf.features[root].cf.split(',').map(Number) );
}
如果我是正确的,

会无限地向leaves Array添加值。

所以,尝试添加类似的内容:

 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浏览器,例如Firefox)。换句话说,如果没有实现,代码就无法运行。

此外,在我看来,您可以添加注释并折叠代码以使其更易于理解。它现在写的方式很简洁,但很难掌握它的基本目的。