if语句的条件太多了?

时间:2014-01-09 18:05:49

标签: ruby if-statement conditional

我正在努力确保输入的罗马数字有效。我的策略是从前一个或两个字符开始,如果字符串中的任何内容无效,那么我告诉他们重新输入他们的号码。如果我这样做,我需要为下面的D,CD,C,XC,L,XL,X,IX,V,IV和I.制定一个条件。我粘贴的方式是编写此条件语句的最佳方式还是更漂亮的方式?

string = "CMCMD"
integer_num = 0

if string[0..1] = "CM"
  if string[2..-1].include? "M" || string[2..-1].include? "CD" || string[2..-1].include? "D" || string[2..-1].include "CM" || string[2..-1].include? "C"
    puts "This is invalid. Please enter your roman numeral correctly."
  else
    add 900 to integer_num and slice CM off the beginning of the string.
  end
end

我查看了文档,以及关于S.O的一些事情,如this one

3 个答案:

答案 0 :(得分:3)

使用Enumerable#any?

尝试以下操作
 if ["M","CD","D","CM","C"].any?{|e| string[2..-1].include? e }

 ary = %w(M CD D CM C)
 if ary.any?(&string[2..-1].method(:include?))

答案 1 :(得分:1)

这是我个人图书馆的一种方法,可将罗马数字字符串转换为数字。您的问题不清楚您认为哪种字符串无效。我的方法试图从罗马字符中最大限度地理解。

class String
  RomanToI = {"i"=>1, "v"=>5, "x"=>10, "l"=>50, "c"=>100, "d"=>500, "m"=>1000}
  def roman_to_i!
    prev = 1000
    downcase.each_char.inject(0) do |i, d|
      raise "Invalid string as Roman numeral" unless d = RomanToI[d]
      (d <= prev) ? prev = d : i -= (prev * 2)
      i += d
    end
  end
end

"mmxiv".roman_to_i! # => 2014
"a".roman_to_i! # => Invalid string as Roman numeral.

答案 2 :(得分:0)

(['M', 'D', 'C'] & string[2..-1].chars).any?

string[2..-1]无法检查'CD',因为除非'C'和'D'也存在,否则'CD'不能出现。与'CM'相同。

string的第一和第二部分确实应该是变量。也许做这样的事情:

cases = {'CM' => {suffix: 'CMD', illegal: ['M', 'D', 'C']},
         'CD' => {...},
         ...}

def invalid?(str, illegal)
  (str.chars & illegal).any?
end

def check_all(cases)
  cases.each do |c, v|  
    if invalid?(v[:suffix], v[:illegal])
      ...
    end
  end
end
相关问题