1

Given a flat one dimensional array of type TreeNode (see interface definition below), I would like to traverse the array and add subsequent array elements as children.

Would be great to do recursively, my shot at non-recursion uses a buffer, but the issue I am facing is how to do node.children[0].children[0]...children[0] as notice that there is only one child per parent.

    Childify(results: TreeNode[]): any {
    var node: TreeNode;
    var buffer: TreeNode;
    var count: number = 0;

    for (var res of results) {
        if (count == 0) {
            node = res[0];
            buffer = res[0];
            buffer.children = [];
            node.children = [];
        } else if (count == 1) {
            buffer.children = res[0];
        } else {
            node = buffer;
            node.children = [];
            node.children.push(res[0]);
            buffer = <TreeNode>node.children;
        }

        count++;
    }
}

Interface definition:

export interface TreeNode {
label?: string;
data?: any;
icon?: any;
expandedIcon?: any;
collapsedIcon?: any;
children?: TreeNode[];  <---------------
leaf?: boolean;
expanded?: boolean;
type?: string;
parent?: TreeNode;
partialSelected?: boolean;
styleClass?: string;
draggable?: boolean;
droppable?: boolean;
selectable?: boolean;

}

The input:

TreeNode[] = [treeNode1, treeNode2, treeNode3, treeNode4,...,treeNodeX]

The output is a TreeNode object, nested by the children property (which is also of TreeNode type):

TreeNode = treeNode1
treeNode1.children = treeNode2
treeNode2.children = treeNode3
treeNode3.children = treeNode4
treeNodeX-1.children = treeNodeX

I don't know how to envoke treeNode1.children[0].children[0]......children[0] dynamically for X number of children in a loop, to assign to the next level of children in treeNode1.

1
  • Based on what are you inserting the nodes? How do you want the resulting three to look like? Commented Feb 12, 2019 at 16:54

2 Answers 2

2
+50

I don't know TypeScript but here's how I'd do this in JavaScript:

const input = [ new TreeNode("node1")
              , new TreeNode("node2")
              , new TreeNode("node3")
              , new TreeNode("node4")
              , new TreeNode("node5")
              ];

const output = input.reduceRight((child, parent) => {
    parent.children.push(child);
    return parent;
});

console.log(output);

function TreeNode(name) {
    this.name = name;
    this.children = [];
}

Hope that helps.

Sign up to request clarification or add additional context in comments.

Comments

1

I've built an algorithm for you. I've built it in simple javascript, but it should be easily modifiable to conform to your typescript interface.

And the code is here:

var flatNodes = [
    {
        name: 'node1',
        children: []
    },
    {
        name: 'node2',
        children: []
    },
    {
        name: 'node3',
        children: []
    },
    {
        name: 'node4',
        children: []
    },
    {
        name: 'node5',
        children: []
    }
];

function linkNodes(flatNodes) {
    flatNodes = flatNodes.slice(); //copy the list

    flatNodes = flatNodes.reverse();

    for (var i = 1; i < flatNodes.length; i++) {
        var previousNode = flatNodes[i - 1];
        var currentNode = flatNodes[i];

        currentNode.children.push(previousNode);
    }

    return flatNodes[flatNodes.length - 1];
}

console.log(linkNodes(flatNodes));

The output is here:

{
    "name": "node1",
    "children": [
        {
            "name": "node2",
            "children": [
                {
                    "name": "node3",
                    "children": [
                        {
                            "name": "node4",
                            "children": [
                                {
                                    "name": "node5",
                                    "children": []
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.