I am working with d3.js to visualise families of animals (organisms) (up to 4000 at a time) as a tree graph, though the data source could just as well be a directory listing, or
Given your starting input I believe something like the following code will produce your desired output. I don't imagine this is the prettiest way to do it, but it's what came to mind at the time.
It seemed easiest to pre-process the data to first split up the initial array of strings into an array of arrays like this:
[
["Hemiptera","Miridae","Kanakamiris" ],
["Hemiptera","Miridae","Neophloeobia","incisa" ],
//etc
]
...and then process that to get a working object in a form something like this:
working = {
Hemiptera : {
Miridae : {
Kanakamiris : {},
Neophloeobia : {
incisa : {}
}
}
},
Lepidoptera : {
Nymphalidae : {
Ephinephile : {
rawnsleyi : {}
}
}
}
}
...because working with objects rather than arrays makes it easier to test whether child items already exist. Having created the above structure I then process it one last time to get your final desired output. So:
// start by remapping the data to an array of arrays
var organisms = data.organisms.map(function(v) {
return v.name.split(".");
});
// this function recursively processes the above array of arrays
// to create an object whose properties are also objects
function addToHeirarchy(val, level, heirarchy) {
if (val[level]) {
if (!heirarchy.hasOwnProperty(val[level]))
heirarchy[val[level]] = {};
addToHeirarchy(val, level + 1, heirarchy[val[level]]);
}
}
var working = {};
for (var i = 0; i < organisms.length; i++)
addToHeirarchy(organisms[i], 0, working);
// this function recursively processes the object created above
// to create the desired final structure
function remapHeirarchy(item) {
var children = [];
for (var k in item) {
children.push({
"name" : k,
"children" : remapHeirarchy(item[k])
});
}
return children;
}
var heirarchy = {
"name" : "ROOT",
"children" : remapHeirarchy(working)
};
Demo: http://jsfiddle.net/a669F/1/