Converting flat structure to hierarchical
This is how I would do it:
var flatArray = [{
Description: "G",
guid: "c8e63b35",
parent: null,
}, {
Description: "Z",
guid: "b1113b35",
parent: "c8e63b35",
}, {
Description: "F",
guid: "d2cc2233",
parent: "b1113b35",
}, {
Description: "L",
guid: "a24a3b1a",
parent: null,
}, {
Description: "K",
guid: "cd3b11caa",
parent: "a24a3b1a",
}];
var recursiveArray = unflatten(flatArray);
alert(JSON.stringify(recursiveArray, null, 4));
<script>
function unflatten(items) {
return items.reduce(insert, {
res: [],
map: {}
}).res;
}
function insert(obj, item) {
var parent = item.parent;
var map = obj.map;
map[item.guid] = item;
if (parent === null) obj.res.push(item);
else {
var parentItem = map[parent];
if (parentItem.hasOwnProperty("Children"))
parentItem.Children.push(item);
else parentItem.Children = [item];
}
return obj;
}
</script>
Of course, this only works if your flatArray
has the property that every parent appears before its children.
Hope that helps.
This one works nicely and is easy to read:
function flatToHierarchy (flat) {
var roots = [] // things without parent
// make them accessible by guid on this map
var all = {}
flat.forEach(function(item) {
all[item.guid] = item
})
// connect childrens to its parent, and split roots apart
Object.keys(all).forEach(function (guid) {
var item = all[guid]
if (item.parent === null) {
roots.push(item)
} else if (item.parent in all) {
var p = all[item.parent]
if (!('Children' in p)) {
p.Children = []
}
p.Children.push(item)
}
})
// done!
return roots
}