从路径组件构造文件树

时间:2012-06-23 00:21:07

标签: ruby ruby-on-rails-3

我有一个像这样的文件路径组件数组:

[ ['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 个答案:

答案 0 :(得分: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这样的宝石,以减少你必须手动做的繁忙工作量。

这也没有做任何“健全性检查”以确保数据不是病态的,例如,你可以构造一个数组,将文件名转换为目录,用文件名擦除目录,等等on - 留给读者的练习。