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!

2 Answers 2

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; }

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you for so quick answer! Im sorry, but parents still represents by id only. What I missed?
do you like to add the parent's node at parent? please see edit.
I need instead "parent": 3 have whole object whit id = 3 i.e. parent: {id: 3, title: 'some title', children: []}. Kind of. Thank you for help!
it is. don't be fooled by the systems reference id.
So do you think I shell use recursion then?
|
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))

1 Comment

Thank you for your answer! My data to work with suppose to be huge, so I'm trying to avoid recursion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.