5

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

4

2 回答 2

6

很抱歉参加聚会迟到了。我在尝试将路径列表分解为嵌套对象时遇到了类似的问题。这是一个小提琴,展示了我最终是如何做到的。

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/

于 2015-06-23T15:32:39.093 回答
3

这当然是可能的,但它需要递归。

您要做的第一件事(事实上,正如您已经想好要做的那样)是在斜杠上拆分。为简单起见,我们将使用map

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

现在我们要将其转换为具有namechildren属性的对象数组。这意味着我们将不得不使用递归。

在这个函数中,我们将按照它们的第一个元素对它们进行第一次分组:

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

然后我们可以递归所有这些(假设我们选择的函数名称是structurize):

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

现在我们有了一个很好的结构。然后我们可以再次使用递归函数对其进行字符串化。由于目录列表只是每个项目名称后跟缩进的目录内容列表,我们可以相当容易地编写:

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

然后,实际做到这一点:

console.log(stringify(structurize(paths)).join("\n"));
于 2013-06-17T06:14:13.077 回答