0

에서 디렉토리 산책에 트위스트 :다음 작업을 수행 할 싶습니다 루비

감안할 때 디렉토리 트리 :

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 

나는 디렉터리와 함께 연주와 루비에서 옵션을 찾기,하지만 내 방식은 너무 무차별 틱 느낌했습니다.

이 기능을 효율적으로 코딩하는 방법이 있습니까? 내가 여기에 루비 트릭을 놓친 것 같아.

감사합니다.

여기 내 접근 방식 :

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 

작동하지만, 지저분한 것 같다.

+2

당신이 게시하시기 바랍니다 수 있습니다 접근? – sunnyrjuneja

+0

완료. 의아해? –

+0

실망스러워 이것을 보지 못했습니다. Ruby로 DICOM 디렉토리를 파싱하고 싶은 사람이라면 누구나이 작업을 원할 것입니다. 과정을 최적화하는 것은 사소한 일이며 SO 형식에 잘 맞는 것처럼 보입니다. –

답변

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 

출력 :

루트/B/파일 1

루트/C/D/E/파일 3

루트/F가/G가/file5

+0

이 솔루션은 특히 많은 파일을 포함하는 디렉토리에서 빠를 것입니다. –

+0

기다려주십시오. Pathname 클래스에서 읽는 중 ... –

+0

Dir.glob ('**/* /') 지시문으로 인해 여러 번 트래버스하지 않아도 솔루션이 더 빠르다고 생각합니다. 나는 이것이 재귀 적으로 디렉토리를 얻을 수있는 방법이라는 것을 깨닫지 못했습니다. 좋은! –

관련 문제