Javascript building tree hierarchy
var array = [{"grandp开发者_运维技巧a","father"}, {"father"}, {"grandpa","father","me"}];
Given the above array, I want to product a java-script object(JSON) like below, that has the parent-child like structure.
{"id":"grandpa",
"children":[
{"id":"father",
"children":[
{"id":"me",
"children":[]
}]
}]
}
If you're asking how you would take a list of hierarchy paths and create a tree structure, here's how you could do it in JavaScript:
function convertToHierarchy(arry /* array of array of strings */)
{
var item, path;
// Discard duplicates and set up parent/child relationships
var children = {};
var hasParent = {};
for (var i = 0; i < arry.length; i++)
{
var path = arry[i];
var parent = null;
for (var j = 0; j < path.length; j++)
{
var item = path[j];
if (!children[item]) {
children[item] = {};
}
if (parent) {
children[parent][item] = true; /* dummy value */
hasParent[item] = true;
}
parent = item;
}
}
// Now build the hierarchy
var result = [];
for (item in children) {
if (!hasParent[item]) {
result.push(buildNodeRecursive(item, children));
}
}
return result;
}
function buildNodeRecursive(item, children)
{
var node = {id:item, children:[]};
for (var child in children[item]) {
node.children.push(buildNodeRecursive(child, children));
}
return node;
}
convertToHierarchy([["1","2"], ["1"], ["1","2","3"]]);
Edit:
Your question is still ambiguous. My previous version assumed these two things:
- Each node ID uniquely identifies a node
- A specified hierarchy path can start at other than the root node
In this sample, I'll assume the following:
- Node IDs are not unique, but they are unique within the children of a particular node
- All hierarchy paths start at the root node of the tree
Here's the code:
function convertToHierarchy(arry /* array of array of strings */)
{
// Build the node structure
var rootNode = {id:"root", children:{}}
for (var i = 0; i < arry.length; i++)
{
var path = arry[i];
buildNodeRecursive(rootNode, path, 0);
}
return rootNode;
}
function buildNodeRecursive(node, path, idx)
{
if (idx < path.length)
{
item = path[idx];
if (!node.children[item])
{
node.children[item] = {id:item, children:{}};
}
buildNodeRecursive(node.children[item], path, idx + 1);
}
}
The hierarchy structure is returned, but the format's a bit different. However, you should get the picture.
I think this should work. I'm using firebug to track the structure of the output.
var el = {"name": "Level 1", "paths" : ["fruits"]};
var el2 = {"name": "Level 3", "paths" : ["fruits", "apples", "fuji"]};
var el3 = {"name": "Level 4", "paths" : ["fruits", "apples", "fuji", "red"]};
var el4 = {"name": "Level 2", "paths" : ["fruits", "apples"]};
var allEl = [el, el2, el3, el4];
/* Define recursive function for setting the child */
function setChild(parent, pos, arr, name)
{
if(pos < arr.length)
{
if(pos == arr.length-1) //last element of the paths
parent.name = name;
if(!parent.children){
parent.children = [];
parent.children[0] = new Object();
}
setChild(parent.children[0], pos + 1, arr, name);
}
}
/* Test starts here */
var root = new Object();
for(var i=0; i<allEl.length; i++)
{
var el = allEl[i];
setChild(root, 0, el.paths, el.name);
}
//Firefox debugging ...getfirebug.com
console.debug(root);
If you want to encode JSON, just use a JSON library.
Don't try and roll your own.
精彩评论