0

I have an array of file path components like this:

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

So the array contains arrays each consisting of path components to a file. The last element in an inner array is always the file itself, with the preceding elements being directories leading to the file.

What I'm trying to figure out is how to transform the above data so that I can easily generate a file tree with it using <ul> and <li> tags such that folders are nested within each other and files within the same folder show up together. All sorted alphabetically.

From the above I would like to generate the following. The file <li> themselves have to be links to the path to that file:

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

Thanks, I'd appreciate any ideas.

4

1 回答 1

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 这样的 gem 来减少你必须手动完成的繁忙工作量。

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

于 2012-06-23T01:03:11.203 回答