Hierarchical json from flat with parent ID

LastTribunal picture LastTribunal · Mar 13, 2013 · Viewed 36.8k times · Source

http://jsfiddle.net/eYgGK/

I stole this script from a different post:

 function convertToHierarchy() {
var arry = [{ "Id": "1", "Name": "abc", "Parent": "", "attr": "abc" },
               { "Id": "2", "Name": "abc", "Parent": "1", "attr": "abc" },
               { "Id": "3", "Name": "abc", "Parent": "2", "attr": "abc" },
               { "Id": "4", "Name": "abc", "Parent": "2", "attr": "abc" }];
        var nodeObjects = createStructure(arry);
        for (var i = nodeObjects.length - 1; i >= 0; i--) {
            var currentNode = nodeObjects[i];
            if (currentNode.value.Parent === "") {
                continue;
            }
            var parent = getParent(currentNode, nodeObjects);

            if (parent === null) {
                continue;
            }

            parent.children.push(currentNode);
            nodeObjects.splice(i, 1);
        }
        console.dir(nodeObjects);
        return nodeObjects;
    }
    function createStructure(nodes) {
        var objects = [];

        for (var i = 0; i < nodes.length; i++) {
            objects.push({ value: nodes[i], children: [] });
        }

        return objects;

    }
    function getParent(child, nodes) {
        var parent = null;

        for (var i = 0; i < nodes.length; i++) {
            if (nodes[i].value.Id === child.value.Parent) {
                return nodes[i];
            }
        }

        return parent;
    }

This script produces:

[{
    "value": {
        "Id": "1",
        "Name": "abc",
        "Parent": "",
        "attr": "abc"
    },
    "children": [{
        "value": {
            "Id": "2",
            "Name": "abc",
            "Parent": "1",
            "attr": "abc"
        },
        "children": [{
            "value": {
                "Id": "4",
                "Name": "abc",
                "Parent": "2",
                "attr": "abc"
            },
            "children": []
        }, {
            "value": {
                "Id": "3",
                "Name": "abc",
                "Parent": "2",
                "attr": "abc"
            },
            "children": []
        }]
    }]
}]

What I'm looking for is:

[{
    "Id": "1",
    "Name": "abc",
    "Parent": "",
    "attr": "abc",
    "children": [{

        "Id": "2",
        "Name": "abc",
        "Parent": "1",
        "attr": "abc",
        "children": [{

            "Id": "4",
            "Name": "abc",
            "Parent": "2",
            "attr": "abc"
        }, {

            "Id": "3",
            "Name": "abc",
            "Parent": "2",
            "attr": "abc"

        }]
    }]
}]

I need to get rid of "value" wrapper primarily, and the empty child node secondarily. I know I can write a clean up script, but that would be less than best practice. Would be great if someone knows how to fix, or suggest a different script!

Thanks

Answer

Arun P Johny picture Arun P Johny · Mar 13, 2013

Try something like

var arry = [{ "Id": "1", "Name": "abc", "Parent": "", "attr": "abc" },
               { "Id": "2", "Name": "abc", "Parent": "1", "attr": "abc" },
               { "Id": "3", "Name": "abc", "Parent": "2", "attr": "abc" },
               { "Id": "4", "Name": "abc", "Parent": "2", "attr": "abc" }];

function convert(array){
    var map = {};
    for(var i = 0; i < array.length; i++){
        var obj = array[i];
        obj.items= [];

        map[obj.Id] = obj;

        var parent = obj.Parent || '-';
        if(!map[parent]){
            map[parent] = {
                items: []
            };
        }
        map[parent].items.push(obj);
    }

    return map['-'].items;

}

var r = convert(arry)

Demo: Fiddle

Result

[{
    "Id" : "1",
    "Name" : "abc",
    "Parent" : "",
    "attr" : "abc",
    "children" : [{
                "Id" : "2",
                "Name" : "abc",
                "Parent" : "1",
                "attr" : "abc",
                "children" : [{
                            "Id" : "3",
                            "Name" : "abc",
                            "Parent" : "2",
                            "attr" : "abc",
                            "children" : []
                        }, {
                            "Id" : "4",
                            "Name" : "abc",
                            "Parent" : "2",
                            "attr" : "abc",
                            "children" : []
                        }]
            }]
}]