2012-06-23 64 views
0

我有文件路径分量的一个这样的数组:构建文件树

[ ['some', 'dir', 'file.txt'], 
    ['other', 'folder', 'here.txt'], 
    ['this', 'one', 'is', 'deeper', 'file.txt'], 
    ['some', 'dir', 'second.txt' 
] 

因此该数组包含阵列每个由路径组件的一个文件。内部数组中的最后一个元素始终是文件本身,前面的元素是通向该文件的目录。

我想弄清楚的是如何转换上述数据,以便我可以使用<ul><li>标签轻松生成文件树,以便文件夹彼此嵌套,同一文件夹内的文件显示在一起。全部按字母顺序排序。

从上面我想生成以下内容。该文件<li>本身必须是链接的路径文件:

<ul> 
    <li>some/ 
    <ul> 
     <li>dir/ 
     <ul> 
      <li><a href="some/dir/file.txt">file.txt</a></li> 
      <li><a href="some/dir/second.txt">second.txt</a></li> 
     </ul> 
     </li> 
    </ul> 
    </li> 
    <li>other/ 
    <ul> 
     <li>folder/ 
     <ul> 
      <li><a href="other/folder/here.txt">here.txt<a/></li> 
     </ul> 
     </li> 
    </ul> 
    </li> 
    <li>this/ 
    <ul> 
     <li>one/ 
     <ul> 
      <li>is/ 
      <ul> 
       <li>deeper/ 
       <ul> 
        <li><a href="this/one/is/deeper/file.txt">file.txt</a></li> 
       </ul> 
       </li> 
      </ul> 
      </li> 
     </ul> 
     </li> 
    </ul> 
    </li> 
</ul> 

谢谢你,我会很感激的任何想法。

回答

1

粗略轮廓;越简单越好(即,没有技巧,让事情变得简单:)

require 'pp' 

dir = {} 

files = [ 
    ['some', 'dir', 'file.txt'], 
    ['other', 'folder', 'here.txt'], 
    ['this', 'one', 'is', 'deeper', 'file.txt'], 
    ['some', 'dir', 'second.txt'] 
] 

def merge_paths(h, paths) 
    top = paths[0] 

    if paths.size == 1 
    h[top] = top 
    else 
    h[top] ||= {} 
    merge_paths h[top], paths[1..-1] 
    end 
end 

files.each do |paths| 
    merge_paths dir, paths 
end 

pp dir 

输出:

{"some"=>{"dir"=>{"file.txt"=>"file.txt", "second.txt"=>"second.txt"}}, 
"other"=>{"folder"=>{"here.txt"=>"here.txt"}}, 
"this"=>{"one"=>{"is"=>{"deeper"=>{"file.txt"=>"file.txt"}}}}} 

创建名单基本上是相同的过程;递归散列键。当一个散列值不是另一个散列值时,你处于最后一个层次。您可能还想按名称和/或类型进行排序,例如,首先放置目录(密钥值为散列值),依此类推。

有很多游戏可以玩这个游戏,包括把它变成几行代码,再加上像deep_merge这样的宝石,以减少你必须手动完成的繁忙工作量。

这也不会做任何“理智检查”,以确保数据不是病态的,例如,您可以构建一个数组,将文件名转换为目录,使用文件名擦除目录,并且如此 - 为读者留下的练习。

+0

谢谢了。这绝对是一个很好的开始。我很感激。 –