JavaScript实现数据转树形结构的两种方法详解

作者:小括号时间:2026-10-30 19:58:18浏览:452

本文详细介绍JavaScript中将平面数据转换为树形结构的两种常用方法:递归法与直接遍历法。递归法适用于多层嵌套数据,需注意React中key的唯一性及搜索配置;遍历法逻辑简单,仅支持单层嵌套。文章结合具体代码示例,解析如何通过id与pid关系构建层级,并提供完整实现思路供参考。

JavaScript将数据处理成树形结构

第一种实现方式采用递归策略

该方案能够处理多层嵌套的数据结构。

需要注意的是,在React环境中,若value与key不一致会触发报错,且key值必须保持唯一。如果数据集合需要支持搜索功能,还需通过treeNodeFilterProp属性指定用于搜索的字段。

若传入的数据已确保包含必要字段,可省略部分校验步骤。此外,递归方法可与第二种方式结合使用,使代码更加简洁。

function toTree(data) {
    for (let i = 0; i < data.length; i++) {
      data[i].value = data[i].id || '';
      data[i].title = data[i].name || '';
      data[i].key = data[i].id || '';
      data[i].children = data[i].list || [];
      if (data[i].children && data[i].children.length > 0) {
        toTree(data[i].children);
      }
    }
    return data;
}

第二种实现方式为直接遍历

此方法仅能处理单层嵌套,但逻辑比递归更为简单。鉴于React允许仅设置value或key其中之一,该方法中无需额外增加key属性。

function toTree(data) {
    return data.map((item) => {
      return {
        title: item.name,
        value: item.id,
        children: item.list.map((item1) => {
          return {
            title: item1.name,
            value: item1.id,
          };
        }),
      };
    });
}

根据id将平级数据转换成树形结构数据

从数据库查询得到的每条记录均包含id和pid字段,需将这些数据转换为树形结构。

id与pid的关系如下:pid为0的数据位于最外层;若某条数据的pid等于最外层数据的id,则该数据置于第二层。

由于层级数量不确定,理论上可存在无限层,需通过循环将数据转换为树形结构:

JavaScript将数据处理成树形结构

// 数据循环
    levelLoop(arr) {
      const returnArr = []; // 返回的数组
      let levelArr = []; // 当前层级的数组
      let lastLevelArr = []; // 上一层数组
      let idLevleArr = []; // 当前层级id的数组
      let lastIdLevleArr = []; // 上一层级id的数组
      let indexLevelArr = []; // 当前层级索引的数组
      return curLoop(arr);
      function curLoop(curArr) {
        curArr.forEach((curItem, curIndex) => {
          if (curItem.pid === 0) {
            // 最外层
            returnArr.push(curItem);
            levelArr.push(curItem);
            idLevleArr.push(curItem.id);
            indexLevelArr.unshift(curIndex); // 添加到最前面,遍历删除元素时从后面开始删除,不会影响index的位置
          } else {
            const lastIndex = lastIdLevleArr.indexOf(curItem.pid);
            if (lastIndex > -1) {
              // 属于上一层级的子级
              // 如果上一层级没有child则添加该属性,此时添加是保证有子元素指向上一层级才添加child
              if (!lastLevelArr[lastIndex].children) {
                lastLevelArr[lastIndex].children = [];
              }
              levelArr.push(curItem);
              lastLevelArr[lastIndex].children.push(curItem);
              idLevleArr.push(curItem.id);
              indexLevelArr.unshift(curIndex);
            }
          }
        });
        lastLevelArr = levelArr;
        levelArr = [];
        lastIdLevleArr = idLevleArr;
        idLevleArr = [];
        indexLevelArr.forEach(index => {
          curArr.splice(index, 1); // 删除当前层级的元素,使总数量不断减少
        });
        indexLevelArr = [];
        if (curArr.length) {
          return curLoop(curArr);
        } else {
          return returnArr;
        }
      }
    }
  },

JavaScript将数据处理成树形结构

JavaScript将数据处理成树形结构

总结

以上内容为个人经验总结,旨在提供参考,感谢大家的支持。

作者最新文章