Search code examples
javascriptarraysjsontreehierarchy

Construct hierarchy tree from flat list with parent field?


I have a list of "page" objects with a parent field. This parent field references another object in the list. I would like to create a tree hierarchy from this list based on this field.

Here is what my original list looks like:

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

I would like to convert it into a tree structure like this:

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

I was hoping for a reusable function that I can call against an arbitrary list any time. Anyone know of a good way to handle this? Any help or advice would be greatly appreciated!


Solution

  • function treeify(list, idAttr, parentAttr, childrenAttr) {
        if (!idAttr) idAttr = 'id';
        if (!parentAttr) parentAttr = 'parent';
        if (!childrenAttr) childrenAttr = 'children';
    
        var treeList = [];
        var lookup = {};
        list.forEach(function(obj) {
            lookup[obj[idAttr]] = obj;
            obj[childrenAttr] = [];
        });
        list.forEach(function(obj) {
            if (obj[parentAttr] != null) {
                if (lookup[obj[parentAttr]] !== undefined) {
                    lookup[obj[parentAttr]][childrenAttr].push(obj);
                } else {
                     //console.log('Missing Parent Data: ' + obj[parentAttr]);
                     treeList.push(obj);
                }               
            } else {
                treeList.push(obj);
            }
        });
        return treeList;
    };
    

    Fiddle