Ruby if语句的条件太多?

Ruby if语句的条件太多?,ruby,if-statement,conditional,Ruby,If Statement,Conditional,我正在努力确保输入的罗马数字是有效的。我的策略是从前一两个字符开始,如果字符串中其后的任何字符无效,我会告诉他们重新输入数字。如果我这样做,我需要为D,CD,C,XC,L,XL,X,IX,V,IV和I做一个条件。下面是CM。我在下面粘贴的方式是写这个条件语句的最佳方式还是有更好的方式 string = "CMCMD" integer_num = 0 if string[0..1] = "CM" if string[2..-1].include? "M" || string[2..-1].i

我正在努力确保输入的罗马数字是有效的。我的策略是从前一两个字符开始,如果字符串中其后的任何字符无效,我会告诉他们重新输入数字。如果我这样做,我需要为D,CD,C,XC,L,XL,X,IX,V,IV和I做一个条件。下面是CM。我在下面粘贴的方式是写这个条件语句的最佳方式还是有更好的方式

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的内容。

试试下面使用

尝试下面使用


这是我个人库中的一个方法,它将罗马数字字符串转换为数字。在你的问题中,你不知道你认为什么样的字符串是无效的。我的方法试图最大限度地理解罗马字符

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.
类字符串
罗马语={“i”=>1,“v”=>5,“x”=>10,“l”=>50,“c”=>100,“d”=>500,“m”=>1000}
定义roman_to_i!
prev=1000
downcase.each_char.injection(0)do|i,d|
提升“无效字符串为罗马数字”,除非d=RomanToI[d]
(d)2014年
“a”.roman_to_i!#=>作为罗马数字的字符串无效。

< /代码> 这是一种从我的个人库中转换罗马数字字符串到数字的方法。在你的问题中,你不清楚你认为什么样的字符串是无效的。我的方法试图最大限度地理解罗马字符。

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.
类字符串
罗马语={“i”=>1,“v”=>5,“x”=>10,“l”=>50,“c”=>100,“d”=>500,“m”=>1000}
定义roman_to_i!
prev=1000
downcase.each_char.injection(0)do|i,d|
提升“无效字符串为罗马数字”,除非d=RomanToI[d]
(d)2014年
“a”.roman_to_i!#=>作为罗马数字的字符串无效。
无需检查
字符串[2..-1]
中的
'CD'
,因为
'CD'
不能存在,除非'C'和'D'也存在。对于
'CM'
也是如此

字符串的第一部分和第二部分实际上应该是变量。也许可以这样做:

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
无需检查
字符串[2..-1]
中的
'CD'
,因为
'CD'
不能存在,除非'C'和'D'也存在。对于
'CM'
也是如此

字符串的第一部分和第二部分实际上应该是变量。也许可以这样做:

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

谢谢!这很漂亮。我将在10分钟内接受答案。谢谢!这很漂亮。我将在10分钟内接受答案。这非常令人印象深刻。我甚至没有完全理解你的代码,sawa,但它在如此少量的代码中工作这一事实非常酷。这非常令人印象深刻。我甚至没有真正理解你的代码sawa完全同意,但它在如此少量的代码中工作的事实是非常酷的。
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