文档章节

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

 甜酒0917
发布于 2016/12/01 13:57
字数 651
阅读 430
收藏 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
博文 13
码字总数 3450
作品 0
武汉
私信 提问
加载中
请先登录后再评论。
Netty那点事(三)Channel与Pipeline

Channel是理解和使用Netty的核心。Channel的涉及内容较多,这里我使用由浅入深的介绍方法。在这篇文章中,我们主要介绍Channel部分中Pipeline实现机制。为了避免枯燥,借用一下《盗梦空间》的...

黄亿华
2013/11/24
2W
22
用vertx实现高吞吐量的站点计数器

工具:vertx,redis,mongodb,log4j 源代码地址:https://github.com/jianglibo/visitrank 先看架构图: 如果你不熟悉vertx,请先google一下。我这里将vertx当作一个容器,上面所有的圆圈要...

jianglibo
2014/04/03
4.1K
3
SQLServer实现split分割字符串到列

网上已有人实现sqlserver的split函数可将字符串分割成行,但是我们习惯了split返回数组或者列表,因此这里对其做一些改动,最终实现也许不尽如意,但是也能解决一些问题。 先贴上某大牛写的s...

cwalet
2014/05/21
9.6K
0
【opencv】图形的绘制

1.矩形图像的绘制: 原函数:void cvRectangle(CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8,int shift=0) img就是需要绘制的图像 pt1 and pt......

其实我是兔子
2014/10/08
1.2K
1
Swift百万线程攻破单例(Singleton)模式

一、不安全的单例实现 在上一篇文章我们给出了单例的设计模式,直接给出了线程安全的实现方法。单例的实现有多种方法,如下面: class SwiftSingleton { } 这段代码的实现,在shared中进行条...

一叶博客
2014/06/20
3.4K
16

没有更多内容

加载失败,请刷新页面

加载更多

开源FPGA单板iCESugar

随着产业的发展,近年来FPGA越来越得到市场的重视,5G、矿机、人工智能、图像识别、risc-v、通信等众多领域均可见到FPGA的身影,目前比较知名的FPGA厂商有xilinx、altera、lattice等,其中x...

whoisliang
3分钟前
0
0
合并记录帮助文档

合并记录步骤用于将两个不同来源的数据合并,这两个来源的数据分别为旧数据和新数据;该步骤将旧数据和新数据按照指定的关键字匹配、比较、合并,并显示差异信息。接下来就详细介绍一下该步骤...

osc_slnrw1du
3分钟前
0
0
Spark之RDD转换算子(transformation)大全

前面已经给大家讲过RDD原理,今天就给大家说说RDD的转换算子有哪些,以便大家理解。 对于转换操作,RDD的所有转换都不会直接计算结果,仅记录作用于RDD上的操作,当遇到动作算子(Action)时...

osc_3nr2bq5w
4分钟前
0
0
自定义常量数据帮助文档

自定义常量数据步骤主要用于增加自定义字段和行集数据到流中,可增加多个字段并为每个字段赋予行集的值。步骤配置信息如图1所示。 图1 自定义常量数据步骤配置信息 下文详细解释各控件的含义...

osc_r9wwwi0j
5分钟前
0
0
Linux安装配置ftp(Ceonts 7)

1、安装vsftpd yum -y install vsftpd (我这里已经安装好了,只要不报错即安装成功) 安装完成后可以在/etc/vsftpd目录下看到vsftpd.conf 文件,这是vsftp的配置文件。 2、 添加一个ftp用户...

osc_tko37abm
6分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部