简体   繁体   中英

traverse a json tree structure and add all nodes into a list

So i have a json object that i would like to traverse and add all the nodes in a linear list.below is my json

    [{ "name" : "Joe", "age" : "21", "children" : [
        { "name" : "Smith", "age" : "42", "children" : [] },
        { "name" : "Gary", "age" : "21", "children" : [
            { "name" : "Jenifer", "age" : "23", "children" : [
                { "name" : "Dani", "age" : "32", "children" : [] },
                { "name" : "Max", "age" : "34", "children" : [] }
            ]}
        ]}
    ]},
    { "name" : "Albert", "age" : "33", "children" : [] },
    { "name" : "Ron", "age" : "29", "children" : [] }
];

and i want to create a list of all objects present in the tree, objects need to be like this:
{ "name" : "Joe", "age" : "21"}

Using a recursive function is an easy to traverse and flatten your array. Here's a sample algorithim:

 function flatten(items, result = []) { if (items.length) { var item = items.shift(); result.push(item); if (item.children && item.children.length) { result = flatten(item.children, result); } return flatten(items, result); } else { return result; } } var people = [{ "name": "Joe", "age": "21", "children": [{ "name": "Smith", "age": "42", "children": [] }, { "name": "Gary", "age": "21", "children": [{ "name": "Jenifer", "age": "23", "children": [{ "name": "Dani", "age": "32", "children": [] }, { "name": "Max", "age": "34", "children": [] }] }] }] }, { "name": "Albert", "age": "33", "children": [] }, { "name": "Ron", "age": "29", "children": [] }]; console.log(flatten(people));

The easiest way to solve this would be to transverse your tree structure by using recursive function.

In my solution I make use of the instanceOf API to check what type of element the transverse is at and then determine what actions to be taken.

See:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/instanceof

Example:

let result = [];
let people =
    [
      { "name" : "Joe", "age" : "21", "children" : [
        { "name" : "Smith", "age" : "42", "children" : [] },
        { "name" : "Gary", "age" : "21", "children" : [
          { "name" : "Jenifer", "age" : "23", "children" : [
            { "name" : "Dani", "age" : "32", "children" : [] },
            { "name" : "Max", "age" : "34", "children" : [] }
          ]}
        ]}
      ]},
      { "name" : "Albert", "age" : "33", "children" : [] },
      { "name" : "Ron", "age" : "29", "children" : [] }
    ];

function transverse(element, result) {
    if (element instanceof Array)
      element.forEach(item => { transverse(item, result); });
    else if (element instanceof Object) {
      result.push({ name: element.name, age: element.age });
      if (element.hasOwnProperty("children")) {
        transverse(element.children, result);
      }
    }
}

transverse(people, result);
console.log(result);

Output:

[ { name: 'Joe', age: '21' },
  { name: 'Smith', age: '42' },
  { name: 'Gary', age: '21' },
  { name: 'Jenifer', age: '23' },
  { name: 'Dani', age: '32' },
  { name: 'Max', age: '34' },
  { name: 'Albert', age: '33' },
  { name: 'Ron', age: '29' } ]

Assuming it's a simple traversal with no sorting it can be accomplished with two simple functions:

function visitChild(node, array) {
    array[array.length] = { name: node.name, age:node.age };
    if (node.children && node.children.length) {
        node.children.forEach( function(child) { visitChild(child, array); } );
    }
}

function traverseTree(root, list = []) {
    if (root.length) {
        root.forEach( function(node){ visitChild(node, list); });
    }
    return list;
}

console.log( traverseTree(tree) );

Since this has been brought back up, we might want to visit a simpler ES6 solution:

 const extract = (people = []) => people .flatMap (({children = [], ... rest}) => [rest, ... extract (children)]) const people = [{name: "Joe", age: "21", children: [{name: "Smith", age: "42", children: []}, {name: "Gary", age: "21", children: [{name: "Jenifer", age: "23", children: [{name: "Dani", age: "32", children: []}, {name: "Max", age: "34", children: []}]}]}]}, {name: "Albert", age: "33", children: []}, {name: "Ron", age: "29", children: []}] console .log (extract (people))
 .as-console-wrapper {max-height: 100% !important; top: 0}

We implement a very simple (preorder) depth-first traversal of the hierarchy returning everything but the "children" property at each node.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM