0

我有带有代码作为属性的产品类。代码始终是一个数字,根据第一个数字,产品属于某种类型。

If first digit in 0,1,2,3 product is a 'A type'
If first digit in 4,5,6 product is a 'B type'
If first digit in 7,8,9 product is a 'C type'

我正在寻找一种不使用 3 分支if语句来确定产品类型的方法。

有任何想法吗?

4

5 回答 5

3

一种面向对象的方法。显然,该match?方法可以以最能满足您的要求的任何方式编写,也可以根据您的需求变化进行调整——我在这里使用了正则表达式来帮助展示这种方法的灵活性。TYPES常量 &type_for方法应该封装在某个地方,但这取决于你决定在哪里。

class Type
  def initialize name, pattern
    @name = name
    @pattern = pattern
  end

  def match? code
    code =~ @pattern
  end
end

a_type = Type.new 'A', /^[0-3]/
b_type = Type.new 'B', /^[4-6]/
c_type = Type.new 'C', /^[7-9]/
TYPES = [a_type, b_type, c_type]

def type_for product
  TYPES.detect { |type| type.match? product.code }
end
于 2013-01-23T05:04:38.903 回答
2

您是否考虑过使用case声明?我不确定这是否满足您摆脱“3 分支 if 语句”的愿望,但也许它会给您带来其他考虑。

case code[0].to_i
when 0..3 then 'A type'
when 4..6 then 'B type'
when 7..9 then 'C type'
end

我在上面假设“代码”属性实际上存储为字符串,因为您指定第一个数字可以是 0,并且在 Ruby 中,如果它是一个文字整数,它会将您的数字转换为八进制。如果这是一个错误的假设,只需更改 code[0] 位。

这有帮助吗?

于 2013-01-23T03:36:36.313 回答
1

我倾向于在我自己的代码中使用这样的东西,仅仅是因为我宁愿定义一个表来显示与匹配值和预期输出的关系:

HASH = {
  /\A[0-3]/ => 'A type',
  /\A[4-6]/ => 'B type',
  /\A[7-9]/ => 'C type'
}

def get_type(s)
  HASH.keys.each { |regex| 
    return HASH[regex] if s[regex]
  }
end

[ '0001', '3000', '4000', '9000' ].each do |v|
  puts "#{ v } => #{ get_type(v) }"
end

哪个输出:

0001 => A type
3000 => A type
4000 => B type
9000 => C type

我尝试将诸如哈希之类的内容保留在 YAML 文件中,这样我们就不必修改代码来添加其他测试/类型。YAML::load_file()可以使用如下文件轻松初始化 HASH 常量:

---
? !ruby/正则表达式 /\A[4-6]/
: B型

? !ruby/正则表达式 /\A[0-3]/
: 一种

? !ruby/正则表达式 /\A[7-9]/
: C型

并使用简单的puts HASH.to_yaml.

也就是说,我case也强烈支持声明方法。

于 2013-01-23T05:44:54.350 回答
0
def func(code)
  return 'A type' if code[0] == '0'
  ['A','B','C'][(code[0].to_i-1)/3] << ' type'
end

func('0ekrnn')   # => 'A type'
func('4mgm')     # => 'B type'
于 2013-01-23T03:36:58.767 回答
0

您可以使用三元运算符

first_char = code[0].to_i
product_type = [0,1,2,3].include?(first_char) ? "A" : [4,5,6].include?(first_char) ? "B" : [7,8,9].include?(first_char) ? "C" : ""
于 2013-01-23T03:53:26.677 回答