Javascript: Building a hierarchical tree
Here's one solution:
var items = [
{"Id": "1", "Name": "abc", "Parent": "2"},
{"Id": "2", "Name": "abc", "Parent": ""},
{"Id": "3", "Name": "abc", "Parent": "5"},
{"Id": "4", "Name": "abc", "Parent": "2"},
{"Id": "5", "Name": "abc", "Parent": ""},
{"Id": "6", "Name": "abc", "Parent": "2"},
{"Id": "7", "Name": "abc", "Parent": "6"},
{"Id": "8", "Name": "abc", "Parent": "6"}
];
function buildHierarchy(arry) {
var roots = [], children = {};
// find the top level nodes and hash the children based on parent
for (var i = 0, len = arry.length; i < len; ++i) {
var item = arry[i],
p = item.Parent,
target = !p ? roots : (children[p] || (children[p] = []));
target.push({ value: item });
}
// function to recursively build the tree
var findChildren = function(parent) {
if (children[parent.value.Id]) {
parent.children = children[parent.value.Id];
for (var i = 0, len = parent.children.length; i < len; ++i) {
findChildren(parent.children[i]);
}
}
};
// enumerate through to handle the case where there are multiple roots
for (var i = 0, len = roots.length; i < len; ++i) {
findChildren(roots[i]);
}
return roots;
}
console.log(buildHierarchy(items));
Here's another one. This should work for multiple root nodes:
function convertToHierarchy() {
var arry = [{ "Id": "1", "Name": "abc", "Parent": "" },
{ "Id": "2", "Name": "abc", "Parent": "1" },
{ "Id": "3", "Name": "abc", "Parent": "2" },
{ "Id": "4", "Name": "abc", "Parent": "2"}];
var nodeObjects = createStructure(arry);
for (var i = nodeObjects.length - 1; i >= 0; i--) {
var currentNode = nodeObjects[i];
//Skip over root node.
if (currentNode.value.Parent == "") {
continue;
}
var parent = getParent(currentNode, nodeObjects);
if (parent == null) {
continue;
}
parent.children.push(currentNode);
nodeObjects.splice(i, 1);
}
//What remains in nodeObjects will be the root nodes.
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;
}