-1

i am getting a flat object of cms navigation and want to transfer it to a nested object.
The level describes the position of the element in the tree.
Whenever there are subelements they should be stored under a new subCategory.
In every level could be multiple elements.
For example two level 1 categories ("shop service" and "information").

The flat object:

[
    {
        "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"
    }
]

The result should be a nested object with this structure

[
    {
      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' },
  ]

I tried serveral ways, but can't make it.

Thanks in advance.
Stefan

Akiyele
  • 3
  • 2
  • There are really many Q&A on this site on this topic? Have you searched? – trincot Apr 07 '22 at 15:38
  • *"I tried several ways"*: please provide your attempt, and what the problem is with it. – trincot Apr 07 '22 at 15:40
  • Why is the last object in the input array not in the desired output? Why is `level` as string type? What if it does not represent a number? – trincot Apr 07 '22 at 15:42
  • Yes i have searched and read multiple threads to the same topic, but none was similar. The api returns level as string :( thanks for the hint, i have to convert it to a number. – Akiyele Apr 08 '22 at 06:37

1 Answers1

0

You can use a stack to track where you are in the tree while it is being constructed.

It is strange that level has a string data type while clearly its meaning is numeric.

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);
trincot
  • 317,000
  • 35
  • 244
  • 286
  • Thanks!!! It's working. Now i need to figure out what you did. What is the + doing? First time i see this – Akiyele Apr 07 '22 at 16:01
  • It is the [unary plus](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus). – trincot Apr 07 '22 at 16:05
  • Ah ok https://stackoverflow.com/questions/6682997/what-is-the-purpose-of-a-plus-symbol-before-a-variable – Akiyele Apr 07 '22 at 16:08