2012-08-25 77 views
1

我試圖用每個中包含的文件構建一個文件夾數組。所以,如果你的目錄結構:在ruby中生成散列數組的快速方法?

DirA 
    |- FileA 
    \- FileB 
DirB 
    \- FileC 

而且我給出這個數組:

files = ["DirA/FileA", "DirA/FileB", "DirB/FileC"] 

我試圖建立這樣

{DirA => [FileA, FileB], DirB => [FileC]} 

散列現在我m以我認爲是非Rubyish的方式進行操作(假定String具有一個定義獲取父目錄的方法):

h = {} 
files.each do |f| 
    parent = f.getParentDir 
    if not h[parent] then h[parent] = [] end 
    h[parent].push f 
end 

有更優雅的方式嗎?

+1

你只關心直接包含在目錄中的文件,而不是嵌套的文件/目錄? – nneonneo

+0

我使用提供給我的文件列表,我有興趣通過父目錄引用它們,以便我可以檢查它們是否都存在。 –

+1

如果不是h [parent],那麼h [parent] = [] end'可以替換爲 'h [parent] = []除非h [parent]'或者even rubier'h [parent] || = [ ]'。 –

回答

0

我會做

h = {} 
files.each do |f| 
    (h[f.getParentDir] ||= []) << f 
end 
+0

不錯。有更多的好答案,但這是最短的,它使用我在String上定義的方法。在我的實際用例中'getParentPath'是我在'NSURL'上定義的一個方法,但我試圖爲你們簡化事情。乾杯! –

0

這會做的伎倆:

result = files.group_by { |i| i.split("/").first } 
result.each_key { |k| result[k] = result[k].map { |f| f.split("/").last } } 

如果你到簡潔,你可以用

result.merge!(result) { |k, v| v.map { |f| f.split("/").last } } 
0

我想替換第二行你需要這個散列(與數組)

{DirA => [FileA, FileB], DirB => [FileC]} 

files.each_with_object(Hash.new{|h,k|h[k]=[]}) do |m,res| 
    k,v = m.split('/') 
    res[k] << v 
end 
0
files = ["DirA/FileA", "DirA/FileB", "DirB/FileC"] 

files.each_with_object(Hash.new { |h,k| h[k] = [] }) do |path, hash| 
    parent, file = path.split('/', 2) 
    hash[parent] << file 
end 

#=> {"DirA"=>["FileA", "FileB"], "DirB"=>["FileC"]} 
相關問題