Home > OS >  Create a tree from a flattened object
Create a tree from a flattened object

Time:11-09

I have a problem that i can´t figure out, basically i have an Object like:

Object {
   id: string;
   parentId: string;
}

I would like to have a nested Object like:

NestedObject {
id: string;
parentId: string;
children: [
    {
      id: 62,
      parentId: 74,
      children: [{ id: 56, parentId: 62 }, { id: 63, parentId: 62 }],
    }
}

So this function that i figure out, returns me a kind of "nested" object but not really what i need, i can´t see the problem, someone knows where it is? thanks.

function list_to_tree(arr: any[]) { 
 const tree = {
        root: {
            id: "root",
            children: []
        }

    }

    arr.forEach(item => {
        tree[item.id] = {
            ...item,
            children: []
        }
    })

 

    Object.values(tree).forEach(item => {
        if (item.parentId) {
            tree[item.parentId].children.push(item)
            const i = tree[item.parentId]
            tree.root.children.push(i)
        }

    })

    

    return tree.root

}

CodePudding user response:

The easiest way is to store all id and parentId references in an object and omit searching for parents.

This approach creates a note independently from the order of giving data.

After all nodes are visited, the tree is completed.

const
    data = [{ id: 4, parentId: null }, { id: 12, parentId: 133  }, { id: 3, parentId: 4 }, { id: 67, parentId: 98 }, { id: 23, parentId: 3 }, { id: 7, parentId: null }, { id: 134, parentId: 7 }, { id: 3512, parentId: 23 }, { id: 98, parentId: null }, { id: 133, parentId: 23 }],
    tree = function (data, root) {
        const t = {};
        data.forEach(o => {
            Object.assign(t[o.id] = t[o.id] || { id: undefined, parentId: undefined }, o);
            t[o.parentId] ??= {};
            (t[o.parentId].children ??= []).push(t[o.id]);
        });
        return t[root].children;
    }(data, null);

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

  • Related