How to convert a raw data into hierarchical structure
Solution 1:
Please find the solution program, it is bit verbose, since I didn't use any ES6 features. but it still works as per expectation logically.
const data = {
item1: {
chancellor: "my-chancellor-1",
viceChancellor: "my-vice-chancellor-1",
headProfessor: "my-head-professor-1",
student: "student-1",
intern: null,
},
item2: {
chancellor: "my-chancellor-1",
viceChancellor: "my-vice-chancellor-1",
headProfessor: "my-head-professor-1",
student: null,
intern: null,
},
item3: {
chancellor: "my-chancellor-1",
viceChancellor: "my-vice-chancellor-1",
headProfessor: "my-head-professor-1",
student: "student-2",
intern: null,
},
item4: {
chancellor: "my-chancellor-1",
viceChancellor: "my-vice-chancellor-1",
headProfessor: "my-head-professor-1",
student: "student-3",
intern: "intern-1",
},
};
const keyArray = ["chancellor", "viceChancellor", "headProfessor", "student", "intern"]
let output = [];
let parent = null;
Object.keys(data).forEach(dk => {
parent = output.find(el => el.name == data[dk][keyArray[0]]);
keyArray.forEach(kele => {
if (!data[dk][kele]) {
return;
}
let child = {
"keyName": kele,
"name": data[dk][kele]
};
if (!parent) {
output.push(child);
parent = child;
} else {
if (!parent.children)
parent.children = [];
let alreadyPresentChild = parent.children.find(chl => chl.name == child.name);
if (parent.keyName != child.keyName) {
if (!alreadyPresentChild) {
parent.children.push(child);
parent = child;
} else {
parent = alreadyPresentChild;
}
}
}
});
});
console.log(JSON.stringify(output));
Solution 2:
You can build the hierarchy as follows. By keeping a map, keyed by path, you can quickly check whether you already have a node for the current value, or need to create one and add it to the parent's children list:
function createHierarchy(data) {
let tree = { children: [] };
let keys = {};
for (let item of Object.values(data)) {
let node = tree;
let key = "";
for (let keyName of ["chancellor", "viceChancellor", "headProfessor", "student", "intern"]) {
let name = item[keyName];
if (name == null) break;
key += "/" + name;
let child = keys[key]; // Fast lookup
if (!child) {
child = keys[key] = { keyName, name };
(node.children ??= []).push(child);
}
node = child;
}
}
return tree.children;
}
// Demo
const data = {item1: {chancellor: "my-chancellor-1",viceChancellor: "my-vice-chancellor-1",headProfessor: "my-head-professor-1",student: "student-1",intern: null,},item2: {chancellor: "my-chancellor-1",viceChancellor: "my-vice-chancellor-1",headProfessor: "my-head-professor-1",student: null,intern: null,},item3: {chancellor: "my-chancellor-1",viceChancellor: "my-vice-chancellor-1",headProfessor: "my-head-professor-1",student: "student-2",intern: null,},item4: {chancellor: "my-chancellor-1",viceChancellor: "my-vice-chancellor-1",headProfessor: "my-head-professor-1",student: "student-3",intern: "intern-1",},};
console.log(createHierarchy(data));