基于数组生成文件列表

我尝试了一些事情,但本周我觉得我的大脑正在度假,我需要完成这件事……所以我希望有人可以帮助我。

我需要根据保存到数据库中的哈希创建一个文件列表。 看起来像这样:

['file1', 'dir1/file2', 'dir1/subdir1/file3'] 

输出应该是这样的:

  • 文件1
  • DIR1
    • 文件2
    • subdir1
      • 文件3

在HTML中,最喜欢这样(用js扩展它以折叠和多选)

 
  • file1
  • dir1
    • file2
    • subdir1
      • file3

我正在使用Ruby on Rails并试图在RJS模板中实现这一点。 但这并不重要。 你也可以帮我一些详细的伪代码。

有人知道如何解决这个问题吗?


编辑

感谢所有人提供这些解决方案。 列表工作,我将其扩展为可折叠的解决方案,以显示/隐藏目录内容。 我仍然有一个问题:代码的目的是在同步条目后面的复选框中有完整的文件路径。 基于sris的解决方案,我只能读取当前文件并且它是subs,但不能读取root的整个路径。 为了更好地理解:

目前:

 [x] dir1 [x] dir2 [x] file1 

给我

显示相同值的复选框,例如[x] file1的“file1”。 但我需要的是一个完整的路径,例如[x] file1的“dir1 / dir2 / file1”。

有人有另外一个提示如何添加这个?

这是一个可以用于灵感的快速实现。 此实现忽略输入数组中的文件顺序。

我已经更新了解决方案,以便根据需要保存整个路径。

 dirs = ['file1', 'dir1/file2', 'dir1/subdir1/file3', 'dir1/subdir1/file5'] tree = {} dirs.each do |path| current = tree path.split("/").inject("") do |sub_path,dir| sub_path = File.join(sub_path, dir) current[sub_path] ||= {} current = current[sub_path] sub_path end end def print_tree(prefix, node) puts "#{prefix}
    " node.each_pair do |path, subtree| puts "#{prefix}
  • [#{path[1..-1]}] #{File.basename(path)}
  • " print_tree(prefix + " ", subtree) unless subtree.empty? end puts "#{prefix}
" end print_tree "", tree

此代码将像您的示例一样生成正确的缩进HTML。 但由于Ruby中的Hashes(1.8.6)未被订购,因此无法保证文件的顺序。

产生的输出将如下所示:

 
  • [dir1] dir1
  • [dir1/subdir1] subdir1
  • [dir1/subdir1/file3] file3
  • [dir1/subdir1/file5] file5
  • [dir1/file2] file2
  • [file1] file1
  • 我希望这可以作为如何获得路径和文件名的示例。

    想想树。

      # setup phase for each pathname p in list do add_path_to_tree(p) od walk tree depth first, emitting HTML 

    add_path_to_tree是递归的

      given pathname p parse p into first_element, rest # that is, "foo/bar/baz" becomes "foo", "bar/baz" add first_element to tree add_path_to_tree(rest) 

    我将保留树(列表列表)的最佳数据结构(列表列表)作为练习。

    扩展sris的答案,如果您真的想要排序所有内容并在目录之前列出文件,您可以使用以下内容:

     def files_first_traverse(prefix, node = {}) puts "#{prefix}
      " node_list = node.sort node_list.each do |base, subtree| puts "#{prefix}
    • #{base}
    • " if subtree.empty? end node_list.each do |base, subtree| next if subtree.empty? puts "#{prefix}
    • #{base}
    • " files_first_traverse(prefix + ' ', subtree) end puts '#{prefix}
    ' end