Alexey Shevelyov
Alexey Shevelyov

Reputation: 986

How to turn nested objects into array?

I am struggling to what seems to be a trivial task. I need to iterate over this nested object...

[
     {
          "id": "1",
          "name": "Level 1",
          "parent": null,
          "expanded": true,
          "title": "Level 1",
          "children": [
               {
                    "id": "2",
                    "name": "Level 2",
                    "parent": 1,
                    "expanded": true,
                    "title": "Level 2",
                    "children": [
                         {
                              "id": "3",
                              "name": "Level 3",
                              "parent": 2,
                              "expanded": true,
                              "title": "Level 3"
                         }
                    ]
               }
          ]
     }
]

... and end up with below structure.

I have tried .map(Object.values) but that only seems to work partially. What is the most optimal way to get there? What are the alternatives?

 [
  { id: '1', name: 'Level 1', parent: null, expanded: true },
  { id: '2', name: 'Level 2', parent: 1, expanded: true },
  { id: '3', name: 'Level 3', parent: 2, expanded: true }
]

Upvotes: 2

Views: 123

Answers (5)

Yevhen Horbunkov
Yevhen Horbunkov

Reputation: 15530

You need to iterate through nested children recursively, like that:

const obj = {"id":"1","name":"Level 1","parent":null,"expanded":true,"title":"Level 1","children":[{"id":"2","name":"Level 2","parent":1,"expanded":true,"title":"Level 2","children":[{"id":"3","name":"Level 3","parent":2,"expanded":true,"title":"Level 3"}]}]},
 
    flattenObj = ({title, children, ...rest}) => 
      ([rest, ...(children ? children.flatMap(flattenObj) : [])])
    
console.log(flattenObj(obj))
.as-console-wrapper{min-height:100%;}

Upvotes: 2

Rajneesh
Rajneesh

Reputation: 5308

You can build a recursive function to tackle this.

var data = [ { "id": "1", "name": "Level 1", "parent": null, "expanded": true, "title": "Level 1", "children": [ { "id": "2", "name": "Level 2", "parent": 1, "expanded": true, "title": "Level 2", "children": [ { "id": "3", "name": "Level 3", "parent": 2, "expanded": true, "title": "Level 3" } ] } ] }];

let resolve= (array, modified = []) =>{
  array.forEach(({children, ...rest})=>{
   modified.push(rest);
   if(children) resolve(children, modified);
  });
 return modified;
}

console.log(resolve(data))

Upvotes: 2

Narendra Chouhan
Narendra Chouhan

Reputation: 2319

You can try this way, this will work for you

let nestedArrayObj = [{ "id": "1", "name": "Level 1", "parent": null, "expanded": true, "title": "Level 1", "children": [{ "id": "2", "name": "Level 2", "parent": 1, "expanded": true, "title": "Level 2", "children": [{ "id": "3", "name": "Level 3", "parent": 2, "expanded": true, "title": "Level 3" }] }] }]
let nestedArray = []
function nestedArrayFn(nestedArrayObj) {
    nestedArrayObj.forEach(obj => {
        nestedArray.push(JSON.parse(JSON.stringify(obj, ['id', 'name', 'parent', 'expanded'])))
        if (obj.children && obj.children.length) {
            nestedArrayFn(obj.children)
        }
    })
    return nestedArray
}
let finalArray = nestedArrayFn(nestedArrayObj)

console.log(finalArray)

Upvotes: 2

Ele
Ele

Reputation: 33726

Using a recursive approach with the function Array.prototype.map.

let a = [{ id: "1", name: "Level 1", parent: null, expanded: true, title: "Level 1", children: [{ id: "2", name: "Level 2", parent: 1, expanded: true, title: "Level 2", children: [{ id: "3", name: "Level 3", parent: 2, expanded: true, title: "Level 3" }] }] }];

function loop(arr) {
  let nested = [];
  return [].concat(arr.map(({id, name, parent, expanded, children}) => {
     if (children) nested = nested.concat(loop(children));
     return {id, name, parent, expanded};
  }), nested);
}

console.log(loop(a));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386550

You could take a recursive approach and seperate children from the objects and map the rest object and the flat children.

var getFlat = ({ children = [], ...rest }) => [rest, ...children.flatMap(getFlat)],
    data = [{ id: "1", name: "Level 1", parent: null, expanded: true, title: "Level 1", children: [{ id: "2", name: "Level 2", parent: 1, expanded: true, title: "Level 2", children: [{ id: "3", name: "Level 3", parent: 2, expanded: true, title: "Level 3" }] }] }],
    result = data.flatMap(getFlat);

console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 6

Related Questions