将数组转化为树状结构

  • Post author:
  • Post category:其他



转化的过程:

1.数组顺序是乱的,防止处理时有遗漏,需要将第一层级数据先放到数组的前面

2.通过一个对象map存储,键为id 值为对数组遍历修改每一项并添加children:[]

3.最后再次遍历数据,从对象map中取数据和数组的进行比对,父级id为0先放入结果集result,

否则进行递归处理。


附上代码:

//数组转树状结构
/* 
  items:是待处理的成tree的数组
  id:自身id的键名
  pid:父级id的键名
  loopId: 循环可能因为回调函数修改键名而出现错误

  callback:接受回调函数,会接受每一个数据作为参数,可以原有的数据进行处理再返回
*/
export const arrayToTree = function (
  items: Array<any>,
  id: string,
  pid: string,
  callback?: Function,
  loopId?: string,
  loopPid?: string,
) {
  //所有最高级前置 参数id和pid表示对象的自身标识和父类的标识
  items.forEach((item, i) => {
    if (item[pid] === 0) {
      const temp = item;
      items.splice(i, 1);
      items.splice(0, 0, temp);
    }
  });

  const result: any[] = []; // 存放结果集
  const itemMap = {};

  //处理回调函数未传问题
  callback = callback ? callback : (treeItem: Object): Object => treeItem;
  loopId = loopId ? loopId : id
  loopPid = loopPid ? loopPid : pid

  // 先转成map存储
  for (const item of items) {
    itemMap[item[id]] = {
      ...item,
      children: [],
    };
  }

  for (const item of items) {
    const idVal = item[id];
    const pidVal = item[pid];
    const treeItem = itemMap[idVal];
    if (pidVal === 0) {
      result.push(callback(treeItem));
    } else {
      //循环这个过程
      loopTree(result, treeItem, loopId, loopPid, callback);
    }
  }
  return result;
};

const loopTree = (
  result: Array<any>,
  treeItem: Object,
  id: string,
  pid: string,
  callback: Function
) => {
  result.forEach((item) => {
    console.log(item[id],treeItem[id])
    if (item[id] === treeItem[pid]) {
      console.log('loopTree',item)
      item.children.push(callback(treeItem));
    } else {
      loopTree(item.children, treeItem, id, pid, callback);
    }
  });
};

这是我写的一个通用的处理方式,arrayToTree就是主要处理的函数,而loopTree则是递归函数。


参数分析:

第一个参数:待处理成树状结构的数组

第二个参数:代表数组中每一项的id的key

第三个参数:代表数组中每一项的pid(父类id)的key

第四个参数:代表回调函数,回调函数一般用来处理数据,所以传递的是map集合存储的一项数据作为参数传入,这个后面会有事例

第五个参数:代表回调函数处理了新数据的id的key(依据key是否变化)

第六个参数:代表回调函数处理了新数据的pid的key(依据key是否变化)


应用场景:

处理部门管理视图展示时,希望它是以树状结构的形式展示,这里使用组件el-tree,


类型别名代码:


element-ui官方tree组件

export type TreeData = {
    label:string
    value: number
    people?: number
    description: string
    departmentUsers: User[]
    leaderUser: User
    parentDepartmentId:number
    createdAt: string
    children: TreeData[]
}


应用场景处理代码:

 treeData.value = arrayToTree(departments.value,'id','parentDepartmentId',(treeItem)=>{
            return {
                label: treeItem.name,
                value: treeItem.id,
                description: treeItem.description,
                parentDepartmentId: treeItem.parentDepartmentId,
                departmentUsers: treeItem.departmentUsers,
                leaderUser: treeItem.leaderUser,
                createdAt: treeItem.createdAt,
                children: [],
            }
      },'value');

  }

这样扩展的方式有利于处理数据的键值进行转化,从而适配使用的组件。



版权声明:本文为m0_56895352原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。