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. 遞歸創建樹
- 4. 遞歸創建目錄
- 5. 創建文件,遞歸創建目錄
- 6. 樹java的遞歸創建
- 7. 創建一個遞歸目錄樹功能
- 8. 如何在ruby中遞歸創建目錄?
- 9. 木偶遞歸目錄創建
- 10. 爲Node.js創建遞歸目錄0.5.x
- 11. PHP的遞歸目錄創建
- 12. 創建目錄樹
- 13. 通過PHP中的目錄樹遞歸
- 14. 遞歸符號鏈接的目錄樹
- 15. 遞歸樹建設
- 16. python中的樹:創建遞歸子項
- 17. 錯誤創建樹的陣列遞歸
- 18. 創建樹的遞歸函數
- 19. 以遞歸方式創建動態樹
- 20. 從列表遞歸創建樹
- 21. 目錄遞歸
- 22. java.lang.StackOverflowError遞歸目錄
- 23. 使用遞歸的非二叉樹不會創建整個樹
- 24. 遞歸刪除樹目錄結構中的空項目
- 25. Python IOError:[遞歸目錄2]來自遞歸目錄調用
- 26. 遞歸從樹
- 27. F#:遞歸樹
- 28. 遞歸Splay樹
- 29. 樹+遞歸
- 30. 樹叉()遞歸
我做了一個小小的修改,以防止它遍歷太多:'next if(entry =='..'|| entry =='。 ')' 非常感謝您的幫助。對此,我真的非常感激。 – Mem 2011-04-03 18:12:37
啊謝謝,好點。我已經修改了上面的答案。 – Glenjamin 2011-04-03 18:31:59