js实现数组转树结构的递归与非递归实现

递归实现(保存对象属性值,并添加children和levelOnTheTree的属性)

function _initDomTreeObject(ary,data){   
    var data=data?data:(function(ary){
      var tempAry=[];
    var idList=[];
    ary.forEach(function(item){idList.push(item.id)});    
      for(var i=0,len=ary.length;i<len;i++){
        if(ary[i].pid==undefined||(ary[i].pid!=undefined&&deb(ary[i].pid,idList))){
          var obj=ary[i];
          tempAry.push(obj);
        }
       }
        return tempAry; 
    }(ary));
    
  function deb(id,idList){
     var flag=true;
    for(var ida in idList){
      if(id==idList[ida]){
        flag=false;
      }   
    }
     return flag;
   }
  function getParentNode(id,ary){ 
    var parentNode;
    ary.forEach(function(item){
      if(item.id==id){
        parentNode=item;
        return false;
      }
    });
    return parentNode;
  }
   
   function getLevelOnTheTree(ary,dataItem){
     var idList=[];
     ary.forEach(function(item){idList.push(item.id)});
     var level=1;
     while(!deb(dataItem.pid,idList)){
       dataItem=getParentNode(dataItem.pid,ary)
       level++;
     }
      return level;   
   } 

    var temp=0;
   if(data.constructor==Array){
     for(var i=0,len=data.length;i<len;i++){
        for(var j=0,lenA=ary.length;j<lenA;j++){
           if(ary[j].pid==data[i].id){
       var obj=ary[j];
           data[i].children=data[i].children||[];
           data[i].children.unshift(obj);
       temp++;
       }
     }
    }
   }
  

     if(data.constructor==Array){
      for(var n=0,lenB=data.length;n<lenB;n++){
      data[n].levelOnTheTree=getLevelOnTheTree(ary,data[n]);
      if(temp>0){
        data[n].children=_initDomTreeObject(ary,data[n].children?data[n].children:[]);
    if(data[n].children.length==0){
      delete data[n].children;
    }
       }
      } 
    }

  return data;
}

非递归实现 (保存对象属性值,并添加children和levelOnTheTree的属性)

var aaa= [{name:'aaa',id:0},{name:'a',id:1},{name:'b',id:2,pid:1},{name:'c',id:3,pid:1},{name:'d',id:4,pid:2},{name:'e',id:5,pid:2}];

function _initDomTreeObject(sourceAry,data){   
//保存原始数组,以便做比较(不修改原始数据)  
  var ary=[];
  for(var i=0,len=sourceAry.length;i<len;i++){    
    ary[i]=sourceAry[i];
  }
    var data=data?data:(function(ary){
    var tempAry=[];
    var idList=[];
//取得一级菜单,兼容pid为空不存在等各种情况    
    ary.forEach(function(item){idList.push(item.id)});    
      for(var i=0,len=ary.length;i<len;i++){
        if(ary[i].pid==undefined||(ary[i].pid!=undefined&&deb(ary[i].pid,idList))){
          var obj=ary[i];
          ary[i]=null;
//设定一级菜单的层次          
          obj.levelOnTheTree=getLevelOnTheTree(sourceAry,obj);
          tempAry.push(obj);
        }
       }
        return tempAry; 
    }(ary));
//内部方法,用来比较判断    
  function deb(id,idList){
     var flag=true;
    for(var ida in idList){
      if(id==idList[ida]){
        flag=false;
      }   
    }
     return flag;
   }
  //返回父亲节点 
  function getParentNode(id,ary){ 
    var parentNode;
    ary.forEach(function(item){
      if(item.id==id){
        parentNode=item;
        return false;
      }
    });
    return parentNode;
  }
//通过循环判断结点的层次等级   
   function getLevelOnTheTree(ary,dataItem){
     var idList=[];
     ary.forEach(function(item){idList.push(item.id)});
     var level=1;
     while(!deb(dataItem.pid,idList)){
       dataItem=getParentNode(dataItem.pid,ary)
       level++;
     }
      return level;   
   }  

//非递归的核心算法
   function getSelfDom(itemAry,data){
     var  flag=false;
     var  len=data.length;

     for(var i=0;i<data.length;i++){
     console.log("长度",data.length)
       if(itemAry.pid==data[i].id){    
       flag=true;
       data[i].children=data[i].children||[];
//设置各节点的层次级别      
       itemAry.levelOnTheTree=getLevelOnTheTree(sourceAry,itemAry);    
       data[i].children.push(itemAry);
      }else{
        data[i].children&&(data=data.concat(data[i].children));
      
      }    

      if(flag){
 //如果有多个父亲,只找第一个父亲 ,不写此处的话兼容多父亲模式        
        break;
       }
     }
     return {
               flag:flag,
               data:data.slice(0,len)
             };
 }

//非递归的循环出口
   while(ary.length>0){ 
       var itemAry=ary.shift();
       if(itemAry!=null){
       var obj=getSelfDom(itemAry,data);
       if(obj.flag){
            data=obj.data;
       }else{
         ary.push(itemAry);
       }
     }
   }
  return data;
}

var a=_initDomTreeObject(aaa);
  console.log(a)

 

转载于:https://my.oschina.net/u/3071114/blog/798074

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值