开发者

Too much nesting in ruby?

开发者 https://www.devze.com 2023-03-30 06:20 出处:网络
Surely there must be a b开发者_如何学Goetter way of doing this: File.open(\'Data/Networks/to_process.txt\', \'w\') do |out|

Surely there must be a b开发者_如何学Goetter way of doing this:

File.open('Data/Networks/to_process.txt', 'w') do |out|
  Dir['Data/Networks/*'].each do |f|
    if File.directory?(f)
      File.open("#{f}/list.txt").each do |line|
        out.puts File.basename(f) + "/" + line.split(" ")[0]
      end
    end
  end
end 

Cheers!


You can rid of 1 level of nesting by utilizing Guard Clause pattern:

File.open('Data/Networks/to_process.txt', 'w') do |out|
  Dir['Data/Networks/*'].each do |f|
    next unless File.directory?(f)
    File.open("#{f}/list.txt").each do |line|
      out.puts File.basename(f) + "/" + line.split(" ")[0]
    end
  end
end

See Jeff Atwood's article on this approach.


IMHO there's nothing wrong with your code, but you could do the directory globbing and the check from the if in one statement, saving one level of nesting:

Dir.glob('Data/Networks/*').select { |fn| File.directory?(fn) }.each do |f|
  ...
end


Since you're looking for a particular file in each of the directories, just let Dir#[] find them for you, completely eliminating the need to check for a directory. In addition, IO#puts will accept an array, putting each element on a new line. This will get rid of another level of nesting.

File.open('Data/Networks/to_process.txt', 'w') do |out|
  Dir['Data/Networks/*/list.txt'] do |file|
    dir = File.basename(File.dirname(file))
    out.puts File.readlines(file).map { |l| "#{dir}/#{l.split.first}" }
  end
end


Reducing the nesting a bit by separating the input from the output:

directories = Dir['Data/Networks/*'].find_all{|f| File.directory?(f)}
output_lines = directories.flat_map do |f|
  output_lines_for_directory = File.open("#{f}/list.txt").map do |line|
    File.basename(f) + "/" + line.split(" ")[0]
  end
end
File.open('Data/Networks/to_process.txt', 'w') do |out|
  out.puts output_lines.join("\n")
end
0

精彩评论

暂无评论...
验证码 换一张
取 消