JS对象数组的递归排序(二十四)

古语有云: 万恶淫为首,百善孝为先。 我们后辈当自勉。

上一章简单介绍了JS数组的交并差补运算(二十三),如果没有看过,请观看上一章

一. 对象数组的递归排序

在项目开发中,老蝴蝶常常遇到这样的问题, 后端返回一个对象集合,如权限的表, 有 id,parentId,name 这样的自身关联的表, 在后端查询时,查询出来了一些数据,但是这些数据通常是错综复杂的,排序并不明显。 在Oracle 数据库中,可以通过 start with … connect by …语句来进行查询,但是在MySQL数据库中没有这样的用法。 所以,有时候,前端排序也是非常重要的。 这个方法,就是通过 子与父之间的联系,进行相应的排序, 需要id,parentId 这样的字段来进行指定,不需要级别来指定。 如果没有父的话,那么parentId=0,或者是空。

如一个权限表:

有图片。

后端返回给前端的数据格式是,

有图片。

太多,老蝴蝶这儿就简单截个屏两个了。

在表格中,用的是bootstrap-table 表格,响应的结果是:

function handleClientData(res){
	var privilegeList=res.privilegeList?res.privilegeList:[];
	return privilegeList;
}

有图片。

发现,这种展示方式很明显是不可以的。

可以通过一个方法,将响应的对象数组进行改变一下。

二. 通过递归,排序出新的集体。

方法中所用的 Map, 即new Map(), 并不是 JS的Map,而是老蝴蝶找的Map. 关于Map的内容,可以看老蝴蝶以前写的文章: JS的Map详细形式(十八)

深复制 DeepCopy() ,也可以参考老蝴蝶以前写的文章: JS的数组和对象深层拷贝(二十一)

/**
 * 
 * @param data 要排序的对象数组
 * @param idName id的编号名称
 * @param pIdName 父级的编号名称
 */
function listToTree(data,idName,pIdName){
	//最后结果的集合
	var resultData=[];
	//存储 父下面的所有的子的集合。 key为父,value为子的集合。
	var parentMap=new Map();

	//存储第一级别,即刚开始的那个集合。
	 var firstLevelData=[];
	 
	//2。 为了避免造成对原来数据的干扰,进行一个深度的Copy.
	var resultDeepList=deepCopy(data);
	
	$.each(resultDeepList,function(idx,item){
		var oldItem=item;
		if(!item[pIdName]){  //为空,或者值是0时,设置成-1.
			item[pIdName]=-1; 
		}
		//放置父级
		if(parentMap.containsKey(item[pIdName])){
			parentMap.get(item[pIdName]).push(oldItem);
		}else{
			var arr=new Array();
			arr.push(oldItem);
			parentMap.put(item[pIdName],arr);
		}
		//取出第一级别的那些集合。
		
		if(item[pIdName]==-1){
			firstLevelData.push(oldItem);
		}
	})
	diGuiTree(resultData,firstLevelData,parentMap,idName);
	
	return resultData;
}

function diGuiTree(resultData,data,parentMap,idName){ //放置过来的,是每一个的树。
	if(data!=null&&data.length>0){
		for(var i=0,length=data.length;i<length;i++){	
			var single=data[i];
			resultData.push(single);
			//看是否有子级。
			if(parentMap.get(single[idName])){ //有子级
				var sonList=parentMap.get(single[idName]);
				if(sonList&&sonList.length>0){
					diGuiTree(resultData,sonList,parentMap,idName);
				}
			}
		}
		
	}
}

三. 响应时,调用新方法

写好了这个方法,在响应时进行调用。

function handleClientData(res){
	var privilegeList=res.privilegeList?res.privilegeList:[];
	//return privilegeList; //以前的调用形式
	var resultData=listToTree(privilegeList,"id","parentid");
	return resultData;
}

刷新表格,展示:

有图片。

四. 补充

展示有层次,是因为对 name那一列进行了设置样式。

<th data-field="name" data-align="center" data-cell-style="nameCellStyle">名称</th>
function nameCellStyle(value,row,index,field){
	var level=row.level;
	return {
		css:{
			 "text-align":'left !important',
			"padding-left":(level*40)+"px"
		}
	}
}

谢谢!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

两个蝴蝶飞

你的鼓励,是老蝴蝶更努力写作的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值