我有带有代码作为属性的产品类。代码始终是一个数字,根据第一个数字,产品属于某种类型。
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
语句来确定产品类型的方法。
有任何想法吗?
我有带有代码作为属性的产品类。代码始终是一个数字,根据第一个数字,产品属于某种类型。
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
语句来确定产品类型的方法。
有任何想法吗?
一种面向对象的方法。显然,该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
您是否考虑过使用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] 位。
这有帮助吗?
我倾向于在我自己的代码中使用这样的东西,仅仅是因为我宁愿定义一个表来显示与匹配值和预期输出的关系:
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
也强烈支持声明方法。
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'
您可以使用三元运算符
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" : ""