Home > Net >  JavaScript loop through depth array into a nested object
JavaScript loop through depth array into a nested object

Time:09-17

I'm having some issues translating a depth list into a nested object.

For example, i have a list like so:

"depth": [ 0, 1, 2, 3, 3, 2, 3, 3, 3 ],

And i need to come up with a recursive function to produce an object like this:

"depth": [
        {
            "type": 0,
            "children": [
                {
                    "type": 1,
                    "children": [
                        {
                            "type": 2,
                            "children":[
                                { "type": 3, "children": []},
                                { "type": 3, "children": []},
                            ]
                        },
                        {
                            "type:": 2,
                            "children":[
                                { "type": 3, "children": []},
                                { "type": 3, "children": []},
                                { "type": 3, "children": []},
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

So the rule here, the lower numbers are parents, the higher numbers are siblings to the previous lower number.

So far what i have come up with is:

const depth = [0, 1, 2, 3, 3, 2, 3, 3, 3]

// Start looping through all the numbers in the depth
for (let i = 0; i < depth.length; i  ) { //depth.length

  // As i loop i want to only look at the array i have explored
  // So that i can find the parent that is 1 lower in the array
  let getParent = depth.slice(0, i).lastIndexOf(depth[i] - 1) // position of last lower array

  // Here i check if the current depth item is bigger than the currently lower Item in the array 
  if (depth[i] > depth[getParent]) {
    console.log(depth[i]   " Nesting into "   depth[getParent]) // Is child of that item
  }
}

I think this successfully maps the child to the parent. But now I'm stuck on a way to produce my desired result.

If anyone has an suggestions I would appreciate it a lot.

Thanks

CodePudding user response:

It's easier to create a tree when using an Map or a dictionary (object) to retrieve parents. After reducing the entire tree to a Map, retrieve the root, which holds the entire tree.

const createItem = (type) => ({ type, children: [] })

const fn = (arr, root) => arr.reduce((acc, d) => {  
  const parent = d - 1
  
  const item = createItem(d)
  
  if(d !== root && !acc.has(parent)) acc.set(parent, createItem(parent))
  
  if(d !== root) acc.get(parent).children.push(item)
  
  return acc.set(d, item);
}, new Map()).get(root);

const depth = [0, 1, 2, 3, 3, 2, 3, 3, 3 ]

const result = fn(depth, 0)

console.log(result)

CodePudding user response:

As you get the data in pre-order sequence, you don't actually need a map:

function convert(data) {
    let i = 0;
    
    function getChildren(type) {
        let children = [];
        while (data[i] === type) {
            i  ;
            children.push({
                type,
                children: getChildren(type   1)
            });
        }
        return children;
    }
    
    return getChildren(0);
}

let data = [0, 1, 2, 3, 3, 2, 3, 3, 3];
console.log(convert(data));

  • Related