maxhallinan
maxhallinan

Reputation: 1329

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"
            }
         }
      ]
   }
}

Upvotes: 4

Views: 6060

Answers (2)

Kent Weigel
Kent Weigel

Reputation: 1178

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);
}

Upvotes: 5

Irvin Lim
Irvin Lim

Reputation: 2451

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);

Upvotes: 2

Related Questions