js实现数组转树结构的递归与非递归实现
js实现数组转树结构的递归与非递归实现
甜酒0917 发表于1年前
js实现数组转树结构的递归与非递归实现
  • 发表于 1年前
  • 阅读 32
  • 收藏 0
  • 点赞 0
  • 评论 0

【腾讯云】如何购买服务器最划算?>>>   

递归实现(保存对象属性值,并添加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)

 

共有 人打赏支持
粉丝 1
博文 12
码字总数 3354
×
甜酒0917
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: