2

I stacked with trivial question but can't find the solution. Any help will be appreciated.

I have an array of obects

[
    {
        id: 1,
        title: 'home',
        parent: null,
    },
    {
        id: 2,
        title: 'about',
        parent: null,
    },
    {
        id: 3,
        title: 'team',
        parent: 2,
    },
    {
        id: 4,
        title: 'company',
        parent: 2,
    },
    ,
    {
        id: 5,
        title: 'department',
        parent: 4,
    },
];

To make Tree I use this function: Solution from here

const treeify = (arr) => {
    const tree = [];
    const lookup = {};
    arr.forEach((o) => {
        lookup[o.id] = o;
        lookup[o.id].children = [];
    });
    arr.forEach((o) => {
        if (o.parent !== null) {
            lookup[o.parent].children.push(o);
        } else {
            tree.push(o);
        }
    });
    return tree;
};

And finally I have the tree like so:

[
  {
    "id": 1,
    "title": "home",
    "parent": null,
    "children": []
  },
  {
    "id": 2,
    "title": "about",
    "parent": null,
    "children": [
      {
        "id": 3,
        "title": "team",
        "parent": 2,
        "children": []
      },
      {
        "id": 4,
        "title": "company",
        "parent": 2,
        "children": [
          {
            "id": 5,
            "title": "department",
            "parent": 4,
            "children": []
          }
        ]
      }
    ]
  }
]

The question is: How replace parent ID with object itself?

I want the result like:

            "id": 4,
            "title": "company",
            "parent":  { // <-- how to change just id to object here
                        "id": 2,
                        "title": "about",
                        "parent": null,
                       },
            "children": []

Thank you for help!

Vladimir Vs
  • 1,242
  • 13
  • 12

2 Answers2

1

You could take a single loop approach with a reference for each found node.

const
    data = [{ id: 1, title: 'home', parent: null, }, { id: 2, title: 'about', parent: null }, { id: 3, title: 'team', parent: 2 }, { id: 4, title: 'company', parent: 2 }, { id: 5, title: 'department', parent: 4 }],
    tree = function (data, root) {
        var t = {};
        data.forEach(o => {
            Object.assign(t[o.id] = t[o.id] || {}, o);
            t[o.parent] = t[o.parent] || {};
            t[o.parent].children = t[o.parent].children || [];
            t[o.parent].children.push(t[o.id]);
            if (t[o.id].parent !== null) t[o.id].parent = t[t[o.id].parent];
        });
        return t[root].children;
    }(data, null);

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

You could use reduce method to create recursive function and pass parentId and parent object to the nested recursive calls. And if there is parent object you assign it to current element.

const data = [{"id":1,"title":"home","parent":null},{"id":2,"title":"about","parent":null},{"id":3,"title":"team","parent":2},{"id":4,"title":"company","parent":2},{"id":5,"title":"department","parent":4}]

const treeify = (data, pid = null, parent = null) => {
  return data.reduce((r, e) => {
    if (e.parent === pid) {
      const o = { ...e }
      if (parent) o.parent = parent;

      const children = treeify(data, e.id, e);
      if (children.length) o.children = children;

      r.push(o)
    }

    return r;
  }, [])
}

const result = treeify(data);
console.log(JSON.stringify(result, 0, 4))
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176