Simplifying a Recursive Function

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

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.