Mem*_*Mem 12 ruby directory tree json ruby-on-rails
我需要递归遍历一个目录并创建一个与jsTree控件一起使用的树.控件接受像这样的JSON格式.我需要一些红宝石魔法才能让它干净而迅速地完成.
任何帮助表示赞赏.
Gle*_*min 25
你可能想要这样的东西(未经测试):
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
Run Code Online (Sandbox Code Playgroud)
递归地走下树,建立一个哈希.用你最喜欢的序列化库把它变成json.
首先取出树,将其转换为叶子路径列表,类似于:
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
Run Code Online (Sandbox Code Playgroud)
(不确定上面是否完全符合您的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"]]
Run Code Online (Sandbox Code Playgroud)
然后,对于每条路径,请致电FileUtils#mkdir_p:
paths = leaves_paths tree
paths.each do |path|
FileUtils.mkdir_p(File.join(*path))
end
Run Code Online (Sandbox Code Playgroud)
你应该没问题.
编辑:更简单的版本:
您不需要创建叶子列表,只需遍历整个树并为每个节点创建一个目录:
# 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
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
因此,对于以下结构:
#$ mkdir -p foo/bar
#$ mkdir -p baz/boo/bee
#$ mkdir -p baz/goo
Run Code Online (Sandbox Code Playgroud)
上面的代码返回此哈希:
{
"baz"=>{
"boo"=>{
"bee"=>{}},
"goo"=>{}},
"foo"=>{
"bar"=>{}}}
Run Code Online (Sandbox Code Playgroud)
希望你能够满足你的需求.