Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reverse walk a tree structure

I have XML parsed as JSON. I want to build a React component tree by traversing the JSON and calling React.createElement on each node. The third argument to React.createElement is an array of child React elements. This means that I have to walk down the tree to the leaf nodes, create those React elements first, and then walk back up each branch.

Simple, recursive iteration over a tree structure is simple enough. I'm unsure how to say "okay, now you're at the leaf node, go back up". Are there techniques for this?

Sample data:

{  
   "section":{  
      "attrs":{  
         "class":"foo",
         "data-foo":"foo"
      },
      "#name":"section",
      "children":[  
         {  
            "attrs":{  
               "class":"region-1"
            },
            "#name":"p",
            "children":[  
               {  
                  "attrs":{  
                     "data-children":"true"
                  },
                  "#name":"span"
               }
            ],
            "span":[  
               {  
                  "attrs":{  
                     "data-children":"true"
                  }
               }
            ]
         },
         {  
            "attrs":{  
               "class":"second"
            },
            "#name":"div"
         }
      ],
      "p":[  
         {  
            "attrs":{  
               "class":"region-1"
            },
            "children":[  
               {  
                  "attrs":{  
                     "data-children":"true"
                  },
                  "#name":"span"
               }
            ],
            "span":[  
               {  
                  "attrs":{  
                     "data-children":"true"
                  }
               }
            ]
         }
      ],
      "div":[  
         {  
            "attrs":{  
               "class":"second"
            }
         }
      ]
   }
}
like image 395
maxhallinan Avatar asked Nov 03 '25 12:11

maxhallinan


2 Answers

In general, you can use this algorithm. I used other data for clarity. Your application-specific code goes in place of the console.log statement. For robustness, I added a test for the existence of a children property, and altered the data to test it.

var data = {
    name: 'Parent',
    children: [{
            name: 'Child 1',
            children: [{
                    name: 'Child 1a',
                    children: []
                }, {
                    name: 'Child 1b'
                }
            ]
        }, {
            name: 'Child 2',
            children: [{
                    name: 'Child 2a',
                    children: []
                }, {
                    name: 'Child 2b',
                    children: []
                }
            ]
        }
    ]
};

walk(data);

function walk(node) {
    if (node.children !== undefined) {
        node.children.forEach(function(child) {
            walk(child);
        });
    }

    console.log(node.name);
}
like image 126
Kent Weigel Avatar answered Nov 06 '25 02:11

Kent Weigel


You have already solved half your problem, since you know that you should use recursion to iterate through the tree. But instead of rendering the node as soon as you get to it, render it only at the end of the recursive stack, or after processing all children. This is something like in-order traversal for binary trees.

function iterate(node) {
   if (node.children) {
      node.children.forEach(function (child) {
         iterate(child);
      });
   }

   console.log(node);
}

iterate(section);
like image 20
Irvin Lim Avatar answered Nov 06 '25 04:11

Irvin Lim



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!