2012-08-25 43 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"]} 
相关问题