2

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

Dave
11k3 gold badges45 silver badges54 bronze badges
asked Jul 28, 2016 at 3:30
3
  • 1
    Odd that these people have children older than themselves 😕 Commented Jul 28, 2016 at 4:10
  • Is there any ordering constraint? e.g. Joe is always the first, then followed by his descendants. This continues until no more children nodes are found until then the next node is Albert. Commented Jul 28, 2016 at 4:22
  • no ordering constraint Commented Jul 28, 2016 at 4:34

4 Answers 4

3

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

answered Jul 28, 2016 at 3:54
Sign up to request clarification or add additional context in comments.

Comments

1

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' } ]
answered Jul 28, 2016 at 4:35

3 Comments

@ua_boaz Just in case you met a similar problem in future, you can also consider this as an alternative solution. It basically walks the tree node by node and preserve ordering as well. It also has a little bit less code.
Hi Samuel, another question not sure if you can help... lets say i am trying to find parent of a object, i.e. { "name" : "Max", "age" : "34", "children" : [] }, it should return its parent node object, { "name" : "Jenifer", "a ... } any ideas for that?
@ua_boaz Sure I can help. Do you want to raise another question and I will jump aboard with a solutioN?
0

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) );
answered Jul 28, 2016 at 4:38

Comments

0

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.

answered Oct 8, 2020 at 19:17

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.