I need to build a tree out of materialised paths. My function gets the job done, but I really don’t like the temporary variable that I need to use, not to mention that it wouldn’t work if I were to have nested objects inside, I would need to use e.g. lodash to deep clone the entire object.
Logic
const buildTree = (acc, node, tmpNode) => {
const paths = tmpNode.nodePath.split('/');
const name = paths.shift();
let childNode = (acc.children ??= []).find(i => i.name === name);
tmpNode.nodePath = paths.join('/');
if (!childNode) acc.children.push(childNode = { name, ...node });
if (paths.length) buildTree(childNode, node, tmpNode);
return acc;
};
const tree = list.reduce((acc, node) => buildTree(acc, node, {...node}), { children: [] }).children;
Input data
[
{
label: 'Buttons',
nodePath: 'buttons',
detail: false,
},
{
label: 'Epic',
nodePath: 'buttons/epic',
detail: true,
},
{
label: 'Navigations',
nodePath: 'navigations',
detail: false,
},
{
label: 'Horizontal',
nodePath: 'navigations/horizontal',
detail: false,
},
{
label: 'Advanced',
nodePath: 'navigations/horizontal/advanced',
detail: true,
},
{
label: 'Simmple',
nodePath: 'navigations/horizontal/simple',
detail: true,
},
{
label: 'Vertical',
nodePath: 'navigations/vertical',
detail: false,
},
];
Desired output
[
{
"name": "buttons",
"label": "Buttons",
"nodePath": "buttons",
"detail": false,
"children": [
{
"name": "epic",
"label": "Epic",
"nodePath": "buttons/epic",
"detail": true
}
]
},
{
"name": "navigations",
"label": "Navigations",
"nodePath": "navigations",
"detail": false,
"children": [
{
"name": "horizontal",
"label": "Horizontal",
"nodePath": "navigations/horizontal",
"detail": false,
"children": [
{
"name": "advanced",
"label": "Advanced",
"nodePath": "navigations/horizontal/advanced",
"detail": true
},
{
"name": "simple",
"label": "Simmple",
"nodePath": "navigations/horizontal/simple",
"detail": true
}
]
},
{
"name": "vertical",
"label": "Vertical",
"nodePath": "navigations/vertical",
"detail": false
}
]
}
]
PS1: the property “name” is not needed, but if it stays there, whatever
PS2: the output doesn’t need to be in JSON