我想做以下事情:
给定目录树:
Root
|_dirA
|_dirB
|_file1
|_file2
|_dirC
|_dirD
|_dirE
|_file3
|_file4
|_dirF
|_dirG
|_file5
|_file6
|_file7
...我想走目录树并构建一个数组,其中包含每个目录中至少有一个文件的第一个文件的路径。总体结构可能非常大,文件比目录多得多,所以我想捕获第一个文件的路径而不迭代给定目录中的所有文件。一个文件就足够了。对于上面的树,结果应该看起来像一个只包含:
的数组 root/dirB/file1
root/dirC/dirD/dirE/file3
root/dirF/dirG/file5
我在红宝石中使用了Dir和Find选项,但我的方法感觉太强大了。
是否有一种有效的方法来编写此功能?感觉我在这里错过了一些红宝石技巧。
非常感谢!
这是我的方法:
root="/home/subtest/tsttree/"
Dir.chdir(root)
dir_list=Dir.glob("**/*/") #this invokes recursion
result=Array.new
dir_list.each do |d|
Dir.chdir(root + d)
Dir.open(Dir.pwd).each do |filename|
next if File.directory? filename #some directories may contain only other directories so exclude them
result.push(d + filename)
break
end
end
puts result
工作,但看起来很乱。
答案 0 :(得分:0)
require 'pathname'
# My answer to stackoverflow question posted here:
# http://stackoverflow.com/questions/12684736/a-twist-on-directory-walking-in-ruby
class ShallowFinder
def initialize(root)
@matches = {}
@root = Pathname(root)
end
def matches
while match = next_file
@matches[match.parent.to_s] = match
end
@matches.values
end
private
def next_file
@root.find do |entry|
Find.prune if previously_matched?(entry)
return entry if entry.file?
end
nil
end
def previously_matched?(entry)
return unless entry.directory?
@matches.key?(entry.to_s)
end
end
puts ShallowFinder.new('Root').matches