前后端递归操作树形数据
- 给树形数据添加层级level
- 对树形数据进行操作
源于工作时遇到了个需求,数据处理那块真是让我苦恼不已。我花了一下午的时间…
已知有后端有类似这样的一个树形数据
一个数组里存放了多个实体类,实体类里面有他的child(这里用的字段名为dtoList)
局部展示如下:
客户那边会传递一个层级,我这边显示相应的树形层级数据
注意了没有,后端连个level字段都没有,本来打算在后端加个字段,但是后端是用lamba书写的,本身就难改,搁着我看懂也费劲,果断选择了去前端处理…
开始用的是array.map去操作数组,由于是递归操作,递归本身,又对本身进行修改会出现问题(因此耗费了巨额的时间)、
在同事的帮助下,这里选择了filter创建了个新的数组
//传入参数为数据源以及展示层级
export const filterTreeByLevel = (array, maxLevel) => {
//防止空指针
if (!Array.isArray(array)) return []
const filterData = ((array, level = 1) => {
let filterRes = array.filter(x => {
x.level = level
if (level <= maxLevel) {
return x
}
})
过滤后如果为空,则直接返回
if (filterRes.length < 1)
return null
filterRes.forEach(v => {
if (v.child && v.child.length) {
v.child = filterData(v.child, level + 1)
}
})
return filterRes
});
return filterData(array)
}
前端就这样完美的解决了这次的问题。
在此之后,我利用空余时间,使用后端模拟这样的场景:
已知一个树形结构数据(这里采用代码的形式书写了个简易的数据)
在传入层级为2的情况,直观结果,测试成功
代码如下
package com.example.demo;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class Java3 {
@Test
public void test (){
//数据源
List<DemDTO> dtoList=Data.getData();
int maxLevel=2;
dtoList=handData(maxLevel,dtoList,1);//填入参数依次为显示层数,数据源,起始层级
System.out.println(dtoList);
}
private List<DemDTO> handData(int msxLevel,List<DemDTO> dtoList,int level) {
//给树形数据添加层级,并过滤数据
Stream<DemDTO> clsStream = dtoList.stream().filter(new Predicate<DemDTO>() {
@Override
public boolean test(DemDTO dto) {
//添加层级
dto.setLevel(level);
if(dto.getLevel()<=msxLevel){
return true;
}
return false;
}
});
dtoList = clsStream.collect(Collectors.toList());
//过滤后如果为空,则直接返回
if (dtoList.size()==0){
return null;
}
for (DemDTO dto:dtoList) {
if (dto.getClsList()!=null){
List<DemDTO> clsChildren= handData(msxLevel,dto.getClsList(),level+1);
dto.setClsList(clsChildren);
}
}
return dtoList;
}
}
/** 以下为数据源
* 这里用简易方法处理了个树形数据
*/
class Data{
private static DemDTO dto=new DemDTO();
private Data(){
List<DemDTO> dtoList=new ArrayList<>();
for (int i=0;i<3;i++) {
DemDTO clsDto = new DemDTO();
clsDto.setId("i");
clsDto.setName("第二层"+i);
DemDTO clsDto2 = new DemDTO();
clsDto2.setId("i");
clsDto2.setName("第三层"+i);
List<DemDTO> clsList2=new ArrayList<>();
clsList2.add(clsDto2);
clsDto.setClsList(clsList2);
dtoList.add(clsDto);
}
DemDTO clsDto = new DemDTO();
clsDto.setId("第一层");
clsDto.setName("name");
clsDto.setClsList(dtoList);
this.dto=clsDto;
}
public static List<DemDTO> getData(){
new Data();
List<DemDTO> dtoList=new ArrayList<>();
dtoList.add(dto);
dtoList.add(dto);
return dtoList;
}
}
//简易实体类
class DemDTO{
private int level;
private String name;
private String id;
private List<DemDTO> dtoList;
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public List<DemDTO> getClsList() {
return dtoList;
}
public void setClsList(List<DemDTO> dtoList) {
this.dtoList = dtoList;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
//输出形式我采用了json格式,方便观察测试结果
@Override
public String toString() {
return "{\"name\":\"" + name + '\"' +
", \"id\":\"" + id + '\"' +
", \"level\":" + level +
", \"dtoList\":" + dtoList +
'}';
}
}
至此已完结