if / elsif 到 Ruby 中的 case 语句

if / elsif to case statement in Ruby

我有一个 class,里面有私有方法。我使用 public 方法调用每个私有方法并检查宾果卡是否有宾果游戏。目前是这样写的:

def check_card
    if check_horizontal == true
      bingo = "BINGO!"
    elsif check_vertical == true
      bingo = "BINGO!"
    elsif check_diagonal_right_to_left == true
      bingo = "BINGO!"
    elsif check_diagonal_left_to_right == true
      bingo = "BINGO!"
    else
      bingo = "Sorry, no Bingo."
    end
    puts "The result of your card is: #{bingo}"
  end

这目前有效并通过了我的测试,但是,我希望能够将 if/elsif 语句写成 case 语句并试过这个:

def check_card
  bingo = case @bingo_card
          when check_horizontal then "BINGO!"
          when check_vertical then "BINGO!"
          when check_diagonal_right_to_left then "BINGO!"
          when check_diagonal_left_to_right then "BINGO!"
          else "Sorry, no bingo!"
          end
  puts "The result of your card is: #{bingo}"
end

但是 returns 所有的测试都是 "Sorry, no bingo!"

关于 case 语句语法,我是否遗漏了什么?以下是整个 class:

class BingoScorer
  attr_reader :bingo_card
  def initialize(bingo_card=nil)
    @bingo_card = bingo_card
  end
  def add_card(card)
    @bingo_card = card
  end
  def check_card
    if check_horizontal == true
      bingo = "BINGO!"
    elsif check_vertical == true
      bingo = "BINGO!"
    elsif check_diagonal_right_to_left == true
      bingo = "BINGO!"
    elsif check_diagonal_left_to_right == true
      bingo = "BINGO!"
    else
      bingo = "Sorry, no Bingo."
    end
    puts "The result of your card is: #{bingo}"
  end
  private
  def check_horizontal
    i = 0
    x_index_array = []
    @bingo_card.length.times do
      if @bingo_card[i].join == "xxxxx"
        x_index_array << @bingo_card[i]
      end
      i += 1
    end
    x_index_array.uniq.length == 1 ? true : false
  end
  def check_vertical
    i = 0
    x_index_array = []
    @bingo_card.length.times do
      x_index_array << @bingo_card[i].index('x')
      i += 1
    end
    x_index_array.uniq.length == 1 ? true : false
  end
  def check_diagonal_right_to_left
    i = 0
    x_index_array = []
    @bingo_card.length.times do
      x_index_array << @bingo_card[i][i]
      i += 1
    end
    x_index_array.uniq.length == 1 ? true : false
  end
  def check_diagonal_left_to_right
    idx1 = 0
    idx2 = 4
    x_index_array = []
    @bingo_card.length.times do
      x_index_array << @bingo_card[idx1][idx2]
      idx1 += 1
      idx2 -= 1
    end
    x_index_array.uniq.length == 1 ? true : false
  end
end

谢谢!

您正在将 @bingo_cardcheck_horizontal 等人的价值进行比较。相反,删除 @bingo_card 部分:

def check_card
  bingo = case # nothing here #
          when check_horizontal then "BINGO!"
          when check_vertical then "BINGO!"
          when check_diagonal_right_to_left then "BINGO!"
          when check_diagonal_left_to_right then "BINGO!"
          else "Sorry, no bingo!"
          end
  puts "The result of your card is: #{bingo}"
end

不考虑大小写语法,, your code violates the DRY principle 通过对不同的大小写重复相同的结果。你最好使用逻辑或运算符,||

def check_card
    if check_horizontal || check_vertical ||
       check_diagonal_right_to_left || check_diagonal_left_to_right
      bingo = "BINGO!"
    else
      bingo = "Sorry, no Bingo."
    end

    puts "The result of your card is: #{bingo}"
end

此外,我会像你写其他的那样写check_card,只是returns是对还是错。还有另一个进行格式化的功能。然后 check_card 更容易阅读并且可以重复使用。

def check_card
    return check_horizontal || check_vertical ||
           check_diagonal_right_to_left || check_diagonal_left_to_right
end

def display_result
    if check_card
        bingo = "BINGO!"
    else
        bingo = "Sorry, no Bingo."
    end

    puts "The result of your card is: #{bingo}"
end

稍后您会发现许多使比较易于编写和阅读的绝妙方法。这个呢?

result = "Sorry, no bingo!"
possible_bingos = [
   check_horizontal,
   check_vertical,
   check_diagonal_right_to_left,
   check_diagonal_left_to_right
]
result = "BINGO!" if possible_bingos.any? 

另请注意,您可以在 case 语句行的每行中添加更多选项:

bingo = case @bingo_card
      when horizontal,vertical then "BINGO!"
      when diagonal_right_to_left,diagonal_left_to_right then "BINGO!"
      else "Sorry, no bingo!"
end