首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何重构复杂的if语句ruby

如何重构复杂的if语句ruby
EN

Stack Overflow用户
提问于 2014-12-09 23:56:49
回答 3查看 92关注 0票数 2

现在我遇到了if语句的问题,input.txt

nobita,suneo,1992,1990,15-21,19-21 giant,sizuka,1120,1210,13-21 dorayaki,apple,1147,989,21-19,13-21,21-4

有时是2轮,有时是3轮,或者有时是无效的轮数(例如1轮或大于3轮)。

这是我的代码

代码语言:javascript
复制
require 'csv'

CSV.foreach('input.txt', col_sep: ',') do |row|
  name1, name2, ro1, ro2 = row
  unless row[4]
      puts "no first-round match for #{name1} and #{name2}"
  else
      match1 = row[4]
      m1score1, m1score2 = row[4].split('-')
      if m1score1 > m1score2
          p "Match 1 #{name1} Win, #{name2} Lose"
      end
  end

  unless row[5]
      puts "there is no second round match for #{name1} v #{name2}"
  else
      match2 = row[5]
      m2score1, m2score2 = row[5].split('-')
      if m2score1 > m2score2
          p "Match 2 #{name1} Win, #{name2} Lose"
      end
  end

  unless row[6]
      puts "no third-round match for #{name1} and #{name2}"
  else
      match3 = row[6]
      m3score1, m3score2 = row[6].split('-')
      if m3score1 > m3score2
          p "Match 3 #{name1} Win, #{name2} Lose"
      end
  end
end

我必须做些什么才能简化if语句?

EN

回答 3

Stack Overflow用户

发布于 2014-12-10 00:25:48

输入必须是CSV吗?由于行的长度各不相同,我建议使用不同的结构,如json或其他(如果可能的话)。

如果它必须是CSV,但您可以假设具有特定长度的行将始终具有该长度的正确数据,那么您可以只查看行的长度,以了解您应该做什么。

例如,您的行的长度分别为6、5、7。如果长度为6的行中的数据总是按相同的顺序排列,那么您可以这样做

代码语言:javascript
复制
require 'csv'

CSV.foreach('input.txt', col_sep: ',') do |row|
    DataHandler.handle(row)
end

class DataHandler
  def self.handle(row)
    case row.length
    when 5
      # do stuff when a row has 5 cols
    when 6
      # do stuff when a row has 6 cols
    when 7
      # do stuff when a row has 7 cols
    end
  end
end

例如,如果你有一个缺少的内部列,那么这里的问题就来了。在这种情况下,最好使用占位符,使它们的长度相同,如下所示

代码语言:javascript
复制
apple, ball, cat, 123, 456
thing, this,    , 678, 543
other, blah, dog,    ,
票数 1
EN

Stack Overflow用户

发布于 2014-12-10 00:26:05

试试这个:

代码语言:javascript
复制
require 'csv'

CSV.foreach('input.txt', col_sep: ',') do |row|
  name1, name2, ro1, ro2, *matches = row
  matches.each_with_index do |match, idx|
      m1score1, m1score2 = match.split('-')
      if m1score1.to_i > m1score2.to_i
          p "Match #{idx} #{name1} Win, #{name2} Lose"
      end
  end
  if matches.count < 3
    puts "there were only #{matches.count} matches for #{name1} and #{name2}"
  end
end

当然,我假设如果有第二场比赛,那就必然意味着有第一轮比赛,等等……

此外,我还冒失地将.to_i添加到了m1socrem2score中,因为"3" > "29"...

票数 0
EN

Stack Overflow用户

发布于 2014-12-10 01:07:14

我尝试通过为Match创建一个类来进行重构。您可以通过添加一个Round类来进一步重构。

代码语言:javascript
复制
require 'csv'

class Match
  def initialize(row)
    @player_1, @player_2, @ro1, @ro2, *@rounds = row 
  end

  def get_round(index)
    @rounds[index-1]
  end

  def to_s
    result = "#{@player_1} v #{@player_2}\n"
    (1..3).each do |index|
      if round = get_round(index)
        m1score1, m1score2 = round.split('-')
        if m1score1.to_i > m1score2.to_i
          result += "    Match #{index}: #{@player_1} Wins over #{@player_2}\n"
        end
      else
        result += "    No #{index} round match\n"
      end
    end
    return result
  end
end

CSV.foreach('input.txt', col_sep: ',') do |row|
  match = Match.new(row)
  puts match.to_s + "\n"
end
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27383274

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档