You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于层级字符串Code将扁平化数组转为父子树形数组?

用层级Code将扁平化数组转树形结构的解决方案

我之前也碰到过用层级Code来构建树形结构的需求,递归确实是可行方案,不过咱们可以一步步拆解,把这个问题落地~

核心思路

核心逻辑就是利用Code的.分隔特性,拆解出每个节点的层级关系:

  • 把每个节点的Code按.拆分成层级数组(比如01.05.011拆成['01', '05', '011'])
  • 通过层级数组生成父级Code,找到对应的父节点后挂载
  • 迭代或递归都能实现,先从更直观的迭代方案讲起,再补充递归版本

迭代方案(推荐,避免递归栈溢出)

步骤1:准备测试数据与初始化

先模拟一组扁平化数据,同时创建节点映射表(快速查找父节点)和根树数组:

// 测试用扁平化数组
const flatArray = [
  { id: 1, code: '01', name: '一级节点1' },
  { id: 2, code: '01.05', name: '二级节点1-1' },
  { id: 3, code: '01.05.011', name: '三级节点1-1-1' },
  { id: 4, code: '01.05.011.0001', name: '四级节点1-1-1-1' },
  { id: 5, code: '02', name: '一级节点2' },
  { id: 6, code: '02.03', name: '二级节点2-1' }
];

// 节点映射表:用code做key,存节点引用,方便快速查找父节点
const nodeMap = new Map();
// 最终的树形结构数组
const tree = [];

步骤2:遍历构建树形结构

逐个处理每个节点,拆分Code、找父节点、挂载:

flatArray.forEach(node => {
  // 复制原节点并添加children属性,避免修改原数据
  const treeNode = { ...node, children: [] };
  // 把当前节点存入映射表
  nodeMap.set(treeNode.code, treeNode);
  
  const codeParts = treeNode.code.split('.');
  // 一级节点(只有一个层级)直接加入根树
  if (codeParts.length === 1) {
    tree.push(treeNode);
  } else {
    // 生成父级Code:去掉最后一个层级后拼接
    const parentCode = codeParts.slice(0, -1).join('.');
    // 从映射表中获取父节点
    const parentNode = nodeMap.get(parentCode);
    // 找到父节点就挂载进去
    if (parentNode) {
      parentNode.children.push(treeNode);
    }
  }
});

// 打印结果,就能看到标准树形结构了
console.log(JSON.stringify(tree, null, 2));

递归版本实现

如果一定要用递归,记得先把节点按层级深度排序(浅层级在前),确保递归查找时父节点已被处理:

// 先按Code的层级深度排序,浅层级节点在前
const sortedArray = [...flatArray].sort((a, b) => {
  return a.code.split('.').length - b.code.split('.').length;
});

// 递归构建树形结构的函数
function buildTree(nodes, parentCode = '') {
  const children = [];
  nodes.forEach(node => {
    const codeParts = node.code.split('.');
    // 计算当前节点的父级Code
    const currentParentCode = codeParts.slice(0, -1).join('.');
    // 如果当前节点的父级Code匹配传入的parentCode,就递归找它的子节点
    if (currentParentCode === parentCode) {
      const childNode = { ...node, children: buildTree(nodes, node.code) };
      children.push(childNode);
    }
  });
  return children;
}

const recursiveTree = buildTree(sortedArray);
console.log(JSON.stringify(recursiveTree, null, 2));

关键注意事项

  • Code唯一性:必须保证每个Code是唯一的,否则映射表会覆盖重复Code的节点,导致数据丢失
  • 排序必要性:递归版本一定要先排序,否则父节点可能还没被处理,递归时找不到
  • 容错处理:如果数据中存在父级Code缺失的节点,可以根据需求添加逻辑(比如直接作为根节点,或者打印警告跳过)

内容的提问来源于stack exchange,提问作者Teguh Santoso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:49:13