【js】扁平结构转嵌套结构

126 阅读1分钟

以下是一个示例代码,其中的扁平结构表示为一个数组,每个元素都有一个 id 和一个 parentId(如果是顶级元素,parentIdnull),然后将其转换为嵌套的树结构。

示例数据

const flatArray = [
    { id: 1, name: 'Level 1 - Item 1', parentId: null },
    { id: 2, name: 'Level 2 - Item 1', parentId: 1 },
    { id: 3, name: 'Level 2 - Item 2', parentId: 1 },
    { id: 4, name: 'Level 3 - Item 1', parentId: 2 },
    { id: 5, name: 'Level 1 - Item 2', parentId: null },
];

转换函数

function buildNestedStructure(flatArray) {
    // 创建一个 id 到节点的映射
    const idMapping = flatArray.reduce((acc, el, i) => {
        acc[el.id] = i;
        return acc;
    }, {});

    let root = [];
    flatArray.forEach(el => {
        // 如果是顶级节点
        if (el.parentId === null) {
            root.push(el);
            return;
        }
        // 使用映射找到父节点并添加到其 children 属性中
        const parentEl = flatArray[idMapping[el.parentId]];
        parentEl.children = [...(parentEl.children || []), el];
    });

    return root;
}

const nestedStructure = buildNestedStructure(flatArray);
console.log(JSON.stringify(nestedStructure, null, 2));

解释

  1. idMapping 对象将 id 映射到数组索引,以便快速找到父节点。
  2. flatArray.forEach 遍历扁平数组:
    • 如果 parentIdnull,表示这是一个顶级节点,直接添加到 root 数组中。
    • 否则,找到其父节点,并将当前节点添加到父节点的 children 数组中。

输出

运行上述代码后,nestedStructure 将包含转换后的嵌套结构:

[
  {
    "id": 1,
    "name": "Level 1 - Item 1",
    "parentId": null,
    "children": [
      {
        "id": 2,
        "name": "Level 2 - Item 1",
        "parentId": 1,
        "children": [
          {
            "id": 4,
            "name": "Level 3 - Item 1",
            "parentId": 2
          }
        ]
      },
      {
        "id": 3,
        "name": "Level 2 - Item 2",
        "parentId": 1
      }
    ]
  },
  {
    "id": 5,
    "name": "Level 1 - Item 2",
    "parentId": null
  }
]

这样就成功地将一个扁平结构转换为了嵌套结构。