2

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

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

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

输出应该是这样的:

  • 文件 1
  • 目录1
    • 文件2
    • 子目录1
      • 文件 3

在html中,最好是这样(用js扩展它以折叠和多选)

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

我正在使用 Ruby on Rails 并尝试在 RJS 模板中实现这一点。但这并不重要。您还可以帮助我提供一些详细的伪代码。

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


编辑

感谢大家提供这些解决方案。清单有效,我将其扩展为可折叠的解决方案来显示/隐藏目录内容。我仍然有一个问题:代码旨在在条目后面的复选框中包含完整的文件路径以进行同步。基于 sris 的解决方案,我只能读取当前文件及其子文件,但不能读取根目录的整个路径。为了更好地理解:

目前:

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

给我

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

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

4

3 回答 3

3

这是一个快速实现,您可以从中获得灵感。此实现忽略输入数组中文件的顺序。

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

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>

我希望这可以作为如何获取路径和文件名的示例。

于 2009-04-17T13:04:18.827 回答
1

想想树。

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

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

于 2009-04-17T12:50:18.893 回答
1

扩展 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
于 2009-04-17T13:19:51.037 回答