简体   繁体   English

从路径组件构造文件树

[英]construct file tree from path components

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. 我要弄清楚的是如何转换以上数据,以便可以使用<ul><li>标记轻松地用它生成文件树,从而使文件夹彼此嵌套,而同一文件夹中的文件显示在一起。 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: 文件<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>

Thanks, I'd appreciate any ideas. 谢谢,我将不胜感激。

Rough outline; 粗略轮廓; as simple as possible (ie, no tricks to keep things simple :) 尽可能简单(即没有使事情简单的技巧:)

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

Outputs: 输出:

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

Creating the lists is essentially the same process; 创建列表基本上是相同的过程。 recurse over hash keys. 递归哈希键。 You're at the last level when a hash value isn't another hash. 当哈希值不是另一个哈希值时,您处于最后一级。 You might want to also sort by name and/or type, eg, put directories (key values that are hashes) first, and so on. 您可能还想按名称和/或类型排序,例如,首先放置目录(散列的键值),依此类推。

There are a number of games you can play with this, including turning it into just a few lines of code, combined with gems like deep_merge to reduce the amount of busy-work you have to do manually. 您可以使用多种游戏玩此游戏,包括将其转换成几行代码,并结合使用deep_merge之类的工具,以减少您必须手动进行的繁琐工作。

This also doesn't do any "sanity checking" to make sure the data isn't pathological, eg, you could construct an array that would turn a filename into a directory, wipe out a directory with a filename, and so on--an exercise left for the reader. 这也不会做任何“健全性检查”来确保数据不是病理性的,例如,您可以构造一个将文件名转换为目录,使用文件名擦除目录的数组,依此类推-留给读者的练习。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM