将平面对象转移到嵌套对象 (javascript)

transfer flat object to nested object (javascript)

我正在获取 cms 导航的平面对象,并希望将其传输到嵌套对象。
级别描述了元素在树中的位置。
只要有子元素,它们就应该存储在新的子类别下。
每个级别都可以有多个元素。
例如两个 1 级类别(“商店服务”和“信息”)。

平面对象:

[
    {
        "categoryId": "2002",
        "level": "1",
        "name": "Shop Service"
    },
    {
        "categoryId": "2504",
        "level": "2",
        "name": "Neukunde werden"
    },
    {
        "categoryId": "3501",
        "level": "3",
        "name": "Ebene 3"
    },
    {
        "categoryId": "3503",
        "level": "4",
        "name": "Ebene 4"
    },
    {
        "categoryId": "1009",
        "level": "2",
        "name": "Projektanfrage"
    },
    {
        "categoryId": "1008",
        "level": "2",
        "name": "Kontakt"
    },
    {
        "categoryId": "3502",
        "level": "3",
        "name": "Ebene 3"
    },
    {
        "categoryId": "1019",
        "level": "1",
        "name": "Information"
    },
    {
        "categoryId": "1007",
        "level": "2",
        "name": "Impressum"
    }
]

结果应该是具有这种结构的嵌套对象

[
    {
      categoryId: '2002',
      level: '1',
      name: 'Shop Service',
      subCategory: [
        {
          categoryId: '2504',
          level: '2',
          name: 'Neukunde werden',
          subCategory: {
            categoryId: '3501',
            level: '3',
            name: 'Ebene 3',
            subCategory: { categoryId: '3503', level: '4', name: 'Ebene 4' },
          },
        },
        { categoryId: '1009', level: '2', name: 'Projektanfrage' },
        {
          categoryId: '1008',
          level: '2',
          name: 'Kontakt',
          subCategory: {
            categoryId: '3502',
            level: '3',
            name: 'Ebene 3',
          },
        },
      ],
    },
    { categoryId: '1019', level: '1', name: 'Information' },
  ]

试了好几种方法都做不到

提前致谢。
斯特凡

在构建树时,您可以使用堆栈来跟踪您在树中的位置。

很奇怪 level 有一个字符串数据类型,而它的意思显然是数字。

const data = [{"categoryId": "2002","level": "1","name": "Shop Service"},{"categoryId": "2504","level": "2","name": "Neukunde werden"},{"categoryId": "3501","level": "3","name": "Ebene 3"},{"categoryId": "3503","level": "4","name": "Ebene 4"},{"categoryId": "1009","level": "2","name": "Projektanfrage"},{"categoryId": "1008","level": "2","name": "Kontakt"},{"categoryId": "3502","level": "3","name": "Ebene 3"},{"categoryId": "1019","level": "1","name": "Information"},{"categoryId": "1007","level": "2","name": "Impressum"}];

let hierarchy = []; // The final result -- will be populated below
let path = [hierarchy]; // A stack
for (let obj of data) {
    if (+obj.level < path.length) path.length = obj.level;
    if (+obj.level === path.length) {
        path.at(-1).push(obj);
    } else if (+obj.level === path.length + 1) {
        path.push(path.at(-1).at(-1).subCategory = [obj]);
    } else throw "Unexpected level increase";
}

console.log(hierarchy);