Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
149
rated 0 times [  150] [ 1]  / answers: 1 / hits: 38266  / 11 Years ago, wed, april 3, 2013, 12:00:00

Can anyone help converting the following list of parent-child objects:




[
{
name:root,
_id:root_id,
},
{
name:a1,
parentAreaRef:{
id:root_id,
},
_id:a1_id,
},
{
name:a2,
parentAreaRef:{
id:a1_id,
},
_id:a2_id,
},
{
name:a3,
parentAreaRef:{
id:a2_id,
},
_id:a3_id,
},
{
name:b1,
parentAreaRef:{
id:root_id,
},
_id:b1_id,
},
{
name:b2,
parentAreaRef:{
id:b1_id,
},
_id:b2_id,
},
{
name:b3,
parentAreaRef:{
id:b1_id,
},
_id:b3_id,
}
]


into a tree structure showing the parent-child relationship:




[
{
name: root,
_id:root_id,
children: [
{
name: a1,
_id:a1_id,
children : [
{
name : a2,
_id:a2_id,
children : [
{
name : a3
_id:a3_id
}
]
}
]
},
{
name: b1,
_id:b1_id,
children : [
{
name : b2
_id:b2_id
},
{
name : b3
_id:b3_id
}
]
}
]
}
]


(The output structure is an array to allow for multiple roots but if we can get a solution that handles a single root that's great too.)



The output tree looks like this:





root
|
-- a1
| |
| -- a2
| |
| -- a3
|
-- b1
|
-- b2
-- b3




Thanks!


More From » algorithm

 Answers
2

I have a solution that works. I can give you hints as far as solving it. The good thing is that your data doesn't contain any forward references to nodes. So you can create your tree with just one pass through the array. If note, you will need to make a pass through the entire array first to build up a map of ids to nodes.



Your algorithm will look like this.




  1. Create a map that maps id's to nodes. This will make it easy to look up nodes.

  2. Loop through the array of nodes.

  3. For each element.


    1. Add an entry into the map.

    2. Add a children property (an array) to this node.

    3. Does the element have a parent? If not it must be the root, so assign the this element to the root of the tree.

    4. This element has a parent, so look up the parent node, and then add this current node as a child of the parent node (add it to the children array).




This should help you solve the problem. If you're having specific issues with this algorithm I can point out where the problems are and how to solve it or post the solution and explain how I solved it.



UPDATE



I looked at the solution that you have. You actually don't need recursion for this and you can do this iteratively using the algorithm I described above. You are also modifying the structure in-place, which makes the algorithm more complicated. But you're somewhat on the right track. Here is how I solved it:



var idToNodeMap = {}; //Keeps track of nodes using id as key, for fast lookup
var root = null; //Initially set our loop to null

//loop over data
data.forEach(function(datum) {

//each node will have children, so let's give it a children poperty
datum.children = [];

//add an entry for this node to the map so that any future children can
//lookup the parent
idToNodeMap[datum._id] = datum;

//Does this node have a parent?
if(typeof datum.parentAreaRef === undefined) {
//Doesn't look like it, so this node is the root of the tree
root = datum;
} else {
//This node has a parent, so let's look it up using the id
parentNode = idToNodeMap[datum.parentAreaRef.id];

//We don't need this property, so let's delete it.
delete datum.parentAreaRef;

//Let's add the current node as a child of the parent node.
parentNode.children.push(datum);
}
});


Now root points to the entire tree.



Fiddle.



For the case where the array of elements is in arbitrary order, you will have to initialize idToNodeMap first. The rest of the algorithm remains more-or-less the same (except for the line where you store the node in the map; that's not needed because you did it already in the first pass):



var idToNodeMap = data.reduce(function(map, node) {
map[node._id] = node;
return map;
}, {});

[#79142] Tuesday, April 2, 2013, 11 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
tristab

Total Points: 735
Total Questions: 106
Total Answers: 96

Location: Grenada
Member since Sun, Dec 20, 2020
4 Years ago
tristab questions
Sat, Sep 25, 21, 00:00, 3 Years ago
Sun, Jan 31, 21, 00:00, 3 Years ago
Wed, Dec 2, 20, 00:00, 4 Years ago
Fri, Oct 23, 20, 00:00, 4 Years ago
;