javascriptarraysjsonloopsobject

Iterate nested array of objects and get result as array of object


I am stuck at a problem and i would really need some guidance on the solution. I have an object like this shown below

{
  "count": 3,
  "tree": [
    {
      "name": "Parent1a",
      "children": [
        {
          "name": "Child1a",
          "children": [
            {
              "name": "Child2a",
              "children": [
                {
                  "name": "Child3a",
                  "children": [
                    {
                      "name": "Child4a",
                      "children": []
                    }
                  ]
                }
              ]
            }
          ]
        }
    ]
    },
    {
      "name": "Parent1b",
      "children": [
        {
          "name": "Child1b",
          "children": []
        }
      ]
    }
  ]
}

as you can see in this object above, tree is an array of objects. the above tree consists of 2 objects with name Parent1a and Parent1b. Each of these objects will have children, it will be array of objects too and each children object will further have children array of objects and it can continue n number of times inside each.

we want to get all the name property from all these parent object and all nested array of objects named children and then put those values in a new array of objects.

The final output should look like this.

[
  {
    "id": "Parent1a",
    "label": "Parent1a",
    "level": 0,
  },
  {
    "id": "Child1a",
    "label": "Child1a",
    "parentId": "Parent1a",
    "level": 1,
  },
  {
    "id": "Child2a",
    "label": "Child2a",
    "parentId": "Child1a",
    "level": 2,
  },
  {
    "id": "Child3a",
    "label": "Child3a",
    "parentId": "Child2a",
    "level": 3,
  },
  {
    "id": "Child4a",
    "label": "Child4a",
    "parentId": "Child3a",
    "level": 4,
  },
  {
    "id": "Parent1b",
    "label": "Parent1b",
    "level": 0,
  },
  {
    "id": "Child1b",
    "label": "Child1b",
    "parentId": "Parent1b",
    "level": 1,
  },
  
]

As you can see in above output, Parent1a, Parent1b are the first level. i.e. those are the top level array of objects, hence level been assigned 0 to those. As we dig in deeper through the tree, each children object is assigned next level 1,2,3 and so on as we dig deeper into the children array of objects. similary each children array of object is assigned an id which is the name of its parent tree. Hence Child1a is assigned Parent1a as its parentId.

Can someone let me know how to achieve this as i am really bad at recursion and i checked out few stackoverflow posts but it felt slightly different than what i wanted to achieve. for e.g. Recursive iteration over dynamically nested object array


Solution

  • Below will help in achieving desired result

    While invoking the convertTree function with input , this function will loop through convert.tree and call traverse function with each element of input and item will created with parentId and if there are children it recursively call the traverse function with incremented level

      const convertTree = (input) => {
      const result = []
    
      const traverse = (node, parentId = null, level = 0) => {
        const { name, children } = node
        const item = {
          id: name,
          label: name,
          level: level,
        }
        if (parentId) {
          item.parentId = parentId
        }
        result.push(item)
    
        children.forEach((child) => traverse(child, name, level + 1))
      }
    
      input.tree.forEach((rootNode) => traverse(rootNode))
      return result
    }
    
    // Example usage:
    const input = {
      count: 3,
      tree: [
        {
          name: "Parent1a",
          children: [
            {
              name: "Child1a",
              children: [
                {
                  name: "Child2a",
                  children: [
                    {
                      name: "Child3a",
                      children: [
                        {
                          name: "Child4a",
                          children: [],
                        },
                      ],
                    },
                  ],
                },
              ],
            },
          ],
        },
        {
          name: "Parent1b",
          children: [
            {
              name: "Child1b",
              children: [],
            },
          ],
        },
      ],
    }
    
    const output = convertTree(input)
    console.log(output)