代码之家  ›  专栏  ›  技术社区  ›  pdu

基于数组生成文件列表

  •  2
  • pdu  · 技术社区  · 15 年前

    我试了几次,但这周我觉得我的大脑在休假,我需要完成这件事。所以我希望有人能帮助我。

    我需要基于保存到数据库中的哈希创建一个文件列表。其外观如下:

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

    输出应如下所示:

    • 文件1
    • DR1
      • 文件2
      • 子DRI1
        • 文件3

    在HTML中,最好是这样(用JS扩展它以折叠和多重选择)

    <ul>
      <li>file1
      <li>dir1</li>
      <ul>
        <li>file2</li>
        <li>subdir1</li>
        <ul>
          <li>file3</li>
        </ul>
      </ul>
    </ul>
    

    我正在使用RubyonRails,并尝试在一个RJS模板中实现这一点。但这并不重要。您还可以帮助我处理一些详细的伪代码。

    有人知道怎么解决这个问题吗?


    编辑

    感谢所有人提供这些解决方案。列表有效,我将它扩展到一个可折叠的解决方案来显示/隐藏目录内容。我还有一个问题:代码的目标是在同步条目后面的复选框中有完整的文件路径。基于SRIS的解决方案,我只能读取当前文件及其子文件,而不能从根目录读取整个路径。为了更好地理解:

    目前:

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

    给我

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

    有人有其他提示如何添加这个吗?

    3 回复  |  直到 13 年前
        1
  •  3
  •   sris    15 年前

    这里有一个快速的实现,你可以用它来激发灵感。此实现忽略输入数组中文件的顺序。

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

    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}<ul>"
      node.each_pair do |path, subtree| 
        puts "#{prefix}  <li>[#{path[1..-1]}] #{File.basename(path)}</li>"    
        print_tree(prefix + "  ", subtree) unless subtree.empty?
      end
      puts "#{prefix}</ul>"
    end
    
    print_tree "", tree
    

    这段代码将产生像您的示例一样的适当缩进的HTML。但是,由于Ruby(1.8.6)中的哈希值没有排序,因此无法保证文件的顺序。

    产生的输出如下:

    <ul>
      <li>[dir1] dir1</li>
      <ul>
        <li>[dir1/subdir1] subdir1</li>
        <ul>
          <li>[dir1/subdir1/file3] file3</li>
          <li>[dir1/subdir1/file5] file5</li>
        </ul>
        <li>[dir1/file2] file2</li>
      </ul>
      <li>[file1] file1</li>
    </ul>
    

    我希望这可以作为一个例子,说明如何获取路径和文件名。

        2
  •  1
  •   Charlie Martin    15 年前

    思考树。

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

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

        3
  •  1
  •   Pesto    15 年前

    扩展SRIS的答案,如果您真的希望所有内容都被排序,并且文件列在目录之前,那么您可以使用如下方法:

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