如何将下面结构的数组转成树形结构?

[
  {
    "id": "1699242303156596738",
    "name": "测试a",
    "firstLevel": "1692438402382204930",
    "secondLevel": "1692438402382204939",
    "firstLevelStr": "测试目录1",
    "secondLevelStr": "测试目录1-2",
    "thirdLevel": "",
    "fourthLevel": "",
    "thirdLevelStr": "",
    "fourthLevelStr": "",
  }
  ...
]

扁平数组的结构如上,每个目录下都可以添加数据

如何将这个数组转成树形的结构啊,转成如下的形式
目录层级的name就取对应的 xxxLevelStr

[
        {
          id: 3,
          name: '访视计划',
          children: [
            {
              id: 31,
              name: '研究中心筛选方式',
              children: [
                {
                  id: 33,
                  name: '准备',
                },
                {
                  id: 34,
                  name: '现场访视',
                }
              ]
            },
            {
              id: 32,
              name: '启动访视',
            }
          ]
        },
        {
          id: 1,
          date: '2016-05-02',
          name: '三级目录',
          children: [
            {
              id: 51,
              name: '假设A',
            }
          ]
        },
        {
          id: 2,
          name: '假设C',
        },
        {
          id: 4,
          name: '假设D',
        },
        {
          id: 456,
          name: '假设E',
        }
      ]
阅读 2.6k
2 个回答
function fileList2DirTree(list) {
  
  const dirs = list.reduce((res, item) => {
        // 过滤key带level后缀的即目录结构
    Object.keys(item).filter(k => k.endsWith('Level') && item[k]).forEach((k,i,arr) => {
      // 遍历目录并以key-value形式存储
      // 注意Object.keys返回的key的顺序是和数据的key的添加顺序是一致的
      // 如果数据不是严格按照first下面是second这样的顺序那么需要再排序下
      const dir = res[item[k]] ||= {
        id: item[k],
        name: item[k+'Str'],
        children: [],
        parent: i ? item[arr[i-1]] : null, // 由于数据上没有父子目录关联,这里标识
      };
      // 遍历至末尾则表示文件处于当前目录下,添加该文件
      if(i === arr.length-1) dir.children.push({id: item.id, name: item.name});
    });
    // 返回目录结构树
    return res;
  }, {});

  // 遍历目录树,当目录有父级标识则将自身“拷贝”至该父级目录下
  // 若没有父级标识标识当前为1级目录,push进结果集中
  return Object.values(dirs).reduce((res, dir) => {
    if(!dir.parent) res.push(dir);
    else dirs[dir.parent].children.push(dir);
    return res;
  }, [])
}

fileList2DirTree([
  {
    "id": "1111",
    "name": "测试a",
    "firstLevel": "1",
    "secondLevel": "11",
    "firstLevelStr": "测试目录1",
    "secondLevelStr": "测试目录1-1",
    "thirdLevel": "",
    "fourthLevel": "",
    "thirdLevelStr": "",
    "fourthLevelStr": "",
  },
  {
    "id": "2222222",
    "name": "测试b",
    "firstLevel": "1",
    "secondLevel": "12",
    "firstLevelStr": "测试目录1",
    "secondLevelStr": "测试目录1-2",
  },
    {
    "id": "333333",
    "name": "测试c",
    "firstLevel": "1",
    "secondLevel": "11",
      "thirdLevel": "111",
    "firstLevelStr": "测试目录1",
    "secondLevelStr": "测试目录1-1",
      "thirdLevelStr": "测试目录1-1-1",
  }
])
function arrayToTree(arr) {
  const map = {};
  arr.forEach(item => {
    map[item.id] = { ...item, children: [] };
  });

  const tree = [];
  arr.forEach(item => {
    const node = map[item.id];
    if (item.firstLevel && !item.secondLevel) {
      tree.push(node);
    } else if (item.secondLevel && !item.thirdLevel) {
      map[item.firstLevel].children.push(node);
    } else if (item.thirdLevel && !item.fourthLevel) {
      map[item.secondLevel].children.push(node);
    } else if (item.fourthLevel) {
      map[item.thirdLevel].children.push(node);
    }
  });

  return tree.map(item => ({
    id: item.id,
    name: item.firstLevelStr,
    children: item.children.map(child => ({
      id: child.id,
      name: child.secondLevelStr,
      children: child.children.map(grandChild => ({
        id: grandChild.id,
        name: grandChild.thirdLevelStr,
        children: grandChild.children.map(greatGrandChild => ({
          id: greatGrandChild.id,
          name: greatGrandChild.fourthLevelStr,
          children: greatGrandChild.children,
        })),
      })),
    })),
  }));
}
:
const arr = [ ...数据 ];
const tree = arrayToTree(arr);
console.log(JSON.stringify(tree, null, 2));
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题