10
A
回答
24
你可能想是这样的(未经测试):
def directory_hash(path, name=nil)
data = {:data => (name || path)}
data[:children] = children = []
Dir.foreach(path) do |entry|
next if (entry == '..' || entry == '.')
full_path = File.join(path, entry)
if File.directory?(full_path)
children << directory_hash(full_path, entry)
else
children << entry
end
end
return data
end
递归走在树,建立一个哈希值。把它变成你最喜欢的序列化库的json。
1
Ruby的查找模块(require 'find'
)是简约,但处理目录递归得好:http://www.ruby-doc.org/stdlib/libdoc/find/rdoc/classes/Find.html
+0
感谢您的快速回复。我试图使用Find,但我不确定如何创建树所必需的结构(例如,一个目录具有子目录的子目录以及那些有子目录的子目录等)。 – Mem 2011-04-02 01:40:54
7
首先把你的树,将其转换为路径,以树叶,类似的列表:
def leaves_paths tree
if tree[:children]
tree[:children].inject([]){|acc, c|
leaves_paths(c).each{|p|
acc += [[tree[:name]] + p]
}
acc
}
else
[[tree[:name]]]
end
end
(不当然,如果上面完全遵循你的jsTree结构,但原理是一样的。)
下面是一个输入和输出示例:
tree = {name: 'foo', children: [
{name: 'bar'},
{name: 'baz', children: [
{name: 'boo'},
{name: 'zoo', children: [
{name: 'goo'}
]}
]}
]}
p leaves_paths tree
#=> [["foo", "bar"], ["foo", "baz", "boo"], ["foo", "baz", "zoo", "goo"]]
然后,对于每个通路,向FileUtils#mkdir_p
:
paths = leaves_paths tree
paths.each do |path|
FileUtils.mkdir_p(File.join(*path))
end
而且你应该没问题。
编辑:简单的版本:
你并不需要创建叶的名单,只是遍历整个树,并为每个节点创建一个目录:
# executes block on each tree node, recursively, passing the path to the block as argument
def traverse_with_path tree, path = [], &block
path += [tree[:name]]
yield path
tree[:children].each{|c| traverse_with_path c, path, &block} if tree[:children]
end
traverse_with_path tree do |path|
FileUtils.mkdir(File.join(*path))
end
EDIT2:
哦,对不起,我误解了。所以,这里有一个方法,使基于目录树磁盘上的哈希:
Dir.glob('**/*'). # get all files below current dir
select{|f|
File.directory?(f) # only directories we need
}.map{|path|
path.split '/' # split to parts
}.inject({}){|acc, path| # start with empty hash
path.inject(acc) do |acc2,dir| # for each path part, create a child of current node
acc2[dir] ||= {} # and pass it as new current node
end
acc
}
因此,对于以下结构:
#$ mkdir -p foo/bar
#$ mkdir -p baz/boo/bee
#$ mkdir -p baz/goo
码以上的回报这个哈希:
{
"baz"=>{
"boo"=>{
"bee"=>{}},
"goo"=>{}},
"foo"=>{
"bar"=>{}}}
希望你能设法满足你的需求。
1
我接受的答案在2015年6月份不生效。我将密钥:data
更改为'text'
。我还概括了排除目录和文件的代码。
def directory_hash(path, name=nil, exclude = [])
exclude.concat(['..', '.', '.git', '__MACOSX', '.DS_Store'])
data = {'text' => (name || path)}
data[:children] = children = []
Dir.foreach(path) do |entry|
next if exclude.include?(entry)
full_path = File.join(path, entry)
if File.directory?(full_path)
children << directory_hash(full_path, entry)
else
children << {'icon' => 'jstree-file', 'text' => entry}
end
end
return data
end
相关问题
- 1. 递归创建树
- 2. 如何在ruby中递归创建目录?
- 3. 通过PHP中的目录树递归
- 4. 递归符号链接的目录树
- 5. 递归树建设
- 6. 递归Splay树
- 7. 树叉()递归
- 8. 递归从树
- 9. 树+递归
- 10. F#:递归树
- 11. 递归在Python中创建的目录,而跳过现有目录
- 12. 如何在c中为以下要求创建递归目录?
- 13. 如何在Qt中递归创建一个目录?
- 14. 如何使用Bash递归创建不存在的子目录?
- 15. Bash递归地创建目录而没有最后一个
- 16. 递归创建特定目录中的文件夹
- 17. C目录和子目录递归
- 18. 在JSP上创建目录树结构
- 19. 为文件/目录树创建结构
- 20. 建立目录树
- 21. python脚本,递归目录
- 22. 递归删除目录
- 23. emacs递归删除目录?
- 24. PHP - FTP子目录递归?
- 25. 递归导航子目录
- 26. 递归复制目录
- 27. PHP递归目录路径
- 28. 递归地删除目录
- 29. C中的递归目录
- 30. Makefile子目录递归
我做了一个小小的修改,以防止它遍历太多:'next if(entry =='..'|| entry =='。 ')' 非常感谢您的帮助。对此,我真的非常感激。 – Mem 2011-04-03 18:12:37
啊谢谢,好点。我已经修改了上面的答案。 – Glenjamin 2011-04-03 18:31:59