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

如何将扁平对象数组转换为以ID为键的多层嵌套对象?

我太懂这种多层嵌套绕晕的感觉了——之前处理类似结构时,一开始用递归找父节点,结果数据量一大就卡,还容易出现层级丢失的问题。这里有个高效的动态解法,不管是3层还是更多层都能轻松搞定,核心是用映射表来快速定位父节点,不用反复遍历数组。

解决方案

核心思路拆解

  • 先建一个ID到对象的映射表:把每个对象的ID作为键,对象本身作为值,这样找父节点能直接O(1)定位,不用循环遍历整个数组。
  • 遍历处理每个节点:根节点(parent="0")单独收集,非根节点直接挂到对应父节点的children数组里(没有children就先初始化)。
  • 最后按需输出:可以是根节点数组,也可以转成以根节点ID为键的嵌套对象。

代码示例(JavaScript)

先拿你给的类似输入举个例子,假设输入数组是这样的:

const input = [
  { ID: "1671", parent: "0", name: "部门A" },
  { ID: "1672", parent: "1671", name: "小组A1" },
  { ID: "1673", parent: "1672", name: "成员A1-1" },
  { ID: "1674", parent: "0", name: "部门B" },
  { ID: "1675", parent: "1674", name: "小组B1" }
];

然后写处理函数:

function buildNestedTree(arr) {
  // 1. 建立ID映射表,同时给每个节点初始化children数组(避免修改原数据,用浅拷贝)
  const idMap = {};
  const rootNodes = [];

  // 第一步:填充映射表
  arr.forEach(item => {
    idMap[item.ID] = { ...item, children: [] };
  });

  // 第二步:把每个节点挂载到父节点下
  arr.forEach(item => {
    const currentNode = idMap[item.ID];
    if (item.parent === "0") {
      // 根节点直接加入根数组
      rootNodes.push(currentNode);
    } else {
      // 找到父节点,将当前节点加入children
      const parentNode = idMap[item.parent];
      if (parentNode) { // 防止输入里有无效的parent ID
        parentNode.children.push(currentNode);
      }
    }
  });

  // 如果需要以根节点ID为键的对象,取消下面注释即可
  // const nestedObject = {};
  // rootNodes.forEach(node => {
  //   nestedObject[node.ID] = node;
  // });
  // return nestedObject;

  // 默认返回根节点数组,适合大多数树形展示场景
  return rootNodes;
}

// 调用函数获取结果
const nestedTree = buildNestedTree(input);
console.log(JSON.stringify(nestedTree, null, 2));

运行结果示例

执行后会得到这样的嵌套结构(格式化后):

[
  {
    "ID": "1671",
    "parent": "0",
    "name": "部门A",
    "children": [
      {
        "ID": "1672",
        "parent": "1671",
        "name": "小组A1",
        "children": [
          {
            "ID": "1673",
            "parent": "1672",
            "name": "成员A1-1",
            "children": []
          }
        ]
      }
    ]
  },
  {
    "ID": "1674",
    "parent": "0",
    "name": "部门B",
    "children": [
      {
        "ID": "1675",
        "parent": "1674",
        "name": "小组B1",
        "children": []
      }
    ]
  }
]

为什么这个方法好用?

  • 效率高:只遍历数组两次,时间复杂度O(n),数据量大的时候优势明显。
  • 支持任意深度:不管是3层还是更深的嵌套,逻辑都能自动处理,不用改代码。
  • 容错性强:如果输入里有无效的parent ID(比如父节点不存在),会自动跳过,不会报错。
  • 不修改原数据:用浅拷贝创建新对象,不会影响输入的原始数组。

内容的提问来源于stack exchange,提问作者Anthony O'Neill

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:01:12