项目总结-树形结构数据的处理方法

871 阅读1分钟

前言

在最近项目中,需要按省市来筛选数据,我们得生成对应的树形结构数据。这里记录下数据转换的一些方法。

image.png

树形结构数据生成

在实际项目中,信息一般在后台保存为以下格式:

const datas = [
  { id: 1, parentId: 0 },
  { id: 2, parentId: 1 },
  { id: 3, parentId: 1 },
  ...
];

而前端需要转换为以下格式:

const trees = [
  {
      id: 0,
      childrens: [
         {
             id: 1,
             childrens: [],
         },
         {
             id: 2,
             childrens: [
                 {
                     id: 3,
                     childrens: [],
                 }
             ],
         }
      ],
   },
  ...
];

思路

为了进行数据转换,我们执行以下的步骤:

  1. 声明一个空对象treeKeyObj,用于记录每个id下的子节点。
  2. 遍历datas,根据其parentId信息,更新treeKeyObj中父节点id和对应的子节点数据。
  3. 遍历datas,根据treeKeyObj给每个节点添加childrens,并生成新的数组list
  4. 根据根节点的逻辑,过滤出list中的根节点。

注:由于JavaScript中对象是按引用传递,而这里的节点就是一个对象。所以在第3步中,给节点添加childrens后,其childrens中对应节点也会有相应的childrens

实现

function list2Tree(listParams, filterRootFn) {
    const list = JSON.parse(JSON.stringify(listParams));
    const treeKeyObj = {};
    
    if (list.length > 0) {
        list.forEach(item => {
            const key = item.parentId;

            (treeKeyObj[key] || (treeKeyObj[key] = [])).push(item);
        });

        list.forEach(item => {
            const treeKey = item.id;
            item.childrens = treeKeyObj[treeKey] || [];
        });
    }
    
    return list.filter(filterFn);
}

优化

  • 这里格式里面的idparentIdchildrens,可以作为参数传入来实现动态生成
  • filterRootFn也可以传入一个字符串,用于标识根节点的id值来进行过滤处理

其他(未完待续)

除此之外,还有针对当前节点的所有子节点的查询、所有叶子节点的查询等,就放在后面进行更新。。。