简体   繁体   中英

How to show a list or array into a tree structure in javascript?

I pass this list from python to javascript like this:

 var string=["test_data/new_directory/ok.txt","test_data/reads_1.fq","test_data/test_ref.fa"];

I want output like this:

test_data
  reads_1.fq
  test_ref.fa
  new_directory
    ok.txt

Or also the output could be like this:

test_data
 reads_1.fq
 test_ref.fa

test_data/new_directory
  ok.txt

I used split function to get a list with each file and directory like this:

var string=["test_data/new_directory/ok.txt","test_data/reads_1.fq","test_data/test_ref.fa"];

                                     for(var i=0;i<string.length;i++){

                                         var result = string[i].split('/');

                                          console.log(result);


                                     }

Output looks like this:

["test_data", "new_directory", "ok.txt"]
["test_data", "reads_1.fq"]
["test_data", "test_ref.fa"]

How can I convert into the format I showed above? Thanks

Sorry for being late to the party. I ran into a similar issue trying to break out a list of paths into a nested object. Here's a fiddle showing how I ended up doing it.

var list = [];
list.push("A/B/C");
list.push("A/B/D");
list.push("A/B/C");
list.push("B/D/E");
list.push("D/B/E");
list.push("A/D/C");

var data = [];
for(var i = 0 ; i< list.length; i++)
{
   buildTree(list[i].split('/'),data);    
}
debugger;

function buildTree(parts,treeNode) {
     if(parts.length === 0)
     {
          return; 
     }

     for(var i = 0 ; i < treeNode.length; i++)
     {
          if(parts[0] == treeNode[i].text)
          {
              buildTree(parts.splice(1,parts.length),treeNode[i].children);
              return;
          }
     }

     var newNode = {'text': parts[0] ,'children':[]};
     treeNode.push(newNode);
     buildTree(parts.splice(1,parts.length),newNode.children);
}

https://jsfiddle.net/z07q8omt/

That's certainly possible, but it requires recursion.

The first thing you'll want to do (as you've already figured out to do, in fact) is split on the slashes. We'll use map for simplicity:

paths = paths.map(function(path) { return path.split('/'); });

Now we'll want to convert this into an array of objects with name and children properties. This means we'll have to use recursion.

In this function, we'll do a first pass grouping them by their first element:

var items = [];
for(var i = 0, l = paths.length; i < l; i++) {
    var path = paths[i];
    var name = path[0];
    var rest = path.slice(1);
    var item = null;
    for(var j = 0, m = items.length; j < m; j++) {
        if(items[j].name === name) {
            item = items[j];
            break;
        }
    }
    if(item === null) {
        item = {name: name, children: []};
        items.push(item);
    }
    if(rest.length > 0) {
        item.children.push(rest);
    }
}

Then we can recurse on all of these (assuming the function name we chose was structurize ):

for(i = 0, l = items.length; i < l; i++) {
    item = items[i];
    item.children = structurize(item.children);
}

Now we've got a nice structure. We can then stringify it, again with a recursive function. Since the directory listing is just each item name followed by the indented directory contents listing, we can write that fairly easily:

function stringify(items) {
    var lines = [];
    for(var i = 0, l = items.length; i < l; i++) {
        var item = items[i];
        lines.push(item.name);
        var subLines = stringify(item.children);
        for(var j = 0, m = subLines.length; j < m; j++) {
            lines.push("  " + subLines[j]);
        }
    }
    return lines;
}

Then, to actually do it:

console.log(stringify(structurize(paths)).join("\n"));

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