【问题标题】:Reading files and change function by file names通过文件名读取文件和更改功能
【发布时间】:2017-03-01 01:24:37
【问题描述】:

我有文件读取程序。该程序读取 .txt 文件并对其运行一些功能。 我想按文件名更改功能。 我的 .txt 文件有 A001.txt、B001、C001..等命名规则。 我现在正在使用 if-else 语句来更改功能。

def Function1(input)
  if filename =~ /A.+\.txt/
     some process....
  elsif filename =~ /B.+\.txt/
     some process....
  .....
end

def Funcition2(input)
  if filename =~ /A.+\.txt/
     some process....
  elsif filename =~ /B.+\.txt/
     some process....
      .....
end

我还有 4,5 个类似的功能。 我认为这段代码效率不高且不可读。 读取文件时更改函数的最佳方法是什么?

【问题讨论】:

  • 一个警告。您的第一个正则表达式将匹配文件名BA001.txt,这可能不是您想要的。它也将匹配A001.txt2。您想像/^A.+\.txt$/ 一样锚定正则表达式的开头和结尾。使其不区分大小写也可能有意义。

标签: ruby function file


【解决方案1】:

您可以为此使用 switch 语句 - case。这是之前的回答:How to write a Ruby switch statement (case...when) with regex and backreferences?

基本上是这样的:

filenames.each do |filename|
  case filename
  when /A.+\.txt/
     function 1
  when /B.+\.txt/
     function 2
  else
     function 3
  end
end

【讨论】:

    【解决方案2】:

    我喜欢对这类事情使用动态方法调用:

    def Function1(input)
      prefix  = filename[0].downcase
      handler = "import_#{preview}_file"
      handler = 'import_unknown_file' if !respond_to?(handler)
      send(handler, input)
    end
    
    def import_a_file(input); end
    def import_b_file(input); end
    def import_unknown_file(input); end
    

    您可以更进一步,使其更具可读性:

    HANDLERS_FOR_PREFIXES = {
      'a'       => :import_account_file,
      'b'       => :import_balance_file,
      'default' => :import_other_file
    } 
    
    def Function1(input)
      prefix = filename[0].downcase
      handler = HANDLERS_FOR_PREFIXES[prefix] || HANDLERS_FOR_PREFIXES['default']
      send(handler, input)
    end
    
    def import_account_file(input); end
    

    但是,我怀疑您处理文件的顺序可能很重要(如果您要导入银行信息,则需要先导入账户,然后再将交易导入账户)。所以这样做可能是有意义的:

    FILE_HANDLERS = {
      'A*.txt'  => :import_account_file,
      'T*.txt'  => :import_transaction_file
    } 
    
    def Function1(input)
      FILE_HANDLERS.each do |file_pattern, handler|
        Dir.glob(file_pattern).each do |filename|
          File.open(filename) do |f|
            f.each_line do |line| 
              parsed_line = parse(parse) 
              send(handler, parsed_line);
            end
          end
        end
      end
    end 
    

    虽然我会重构它以删除深层嵌套。

    最后,随着您的代码变得越来越复杂,您可能希望将其分解为单独的类来处理每种类型的文件。这为您提供了很多重用和分解代码的机会。例如:

    class AccountImporter < Importer
      def initialize(input); end
      def process
    end
    
    HANDLERS_FOR_PREFIXES = {
      'a'       => AccountImporter,
      ...
    } 
    
    def Function1(input)
      prefix = filename[0].downcase
      handler = HANDLERS_FOR_PREFIXES[prefix] || HANDLERS_FOR_PREFIXES['default']
      handler.new(input).process
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 2018-12-19
      • 2012-08-22
      相关资源
      最近更新 更多