Ruby 用更灵活的解决方案替换if语句
我有一个产品类,它的属性是代码。代码始终是一个数字,根据第一位数字,产品属于某种类型Ruby 用更灵活的解决方案替换if语句,ruby,Ruby,我有一个产品类,它的属性是代码。代码始终是一个数字,根据第一位数字,产品属于某种类型 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语句来确定产品类型的方法 有什么想法吗?您是否考虑过使用案例陈述?我不确定这是否满足你想要摆脱“3分支i
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
语句来确定产品类型的方法
有什么想法吗?您是否考虑过使用
案例
陈述?我不确定这是否满足你想要摆脱“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
我在上面假设“code”属性实际上存储为字符串,因为您指定第一个数字可以是0,在Ruby中,如果它是一个文本整数,它会将您的数字转换为八进制。如果这是一个错误的假设,只需更改代码[0]位
这有帮助吗?您是否考虑过使用
案例
语句?我不确定这是否满足你想要摆脱“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
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'
我在上面假设“code”属性实际上存储为字符串,因为您指定第一个数字可以是0,在Ruby中,如果它是一个文本整数,它会将您的数字转换为八进制。如果这是一个错误的假设,只需更改代码[0]位
这有帮助吗?def func(代码)
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'
如果代码[0]=“0”,则返回“A类型”
['A'、'B'、'C'][(代码[0]。收件人i-1)/3]“A类型”
func('4mgm')#=>“B型”
def func(代码)
如果代码[0]=“0”,则返回“A类型”
['A'、'B'、'C'][(代码[0]。收件人i-1)/3]“A类型”
func('4mgm')#=>“B型”
您可以使用三元运算符
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" : ""
可以使用三元运算符
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" : ""
一种面向对象的方法。显然,
match?
方法可以以最符合您需求的任何方式编写,也可以根据您的需求变化进行调整——我在这里使用了regex来帮助演示这种方法的灵活性。方法的TYPES
常量和typeu应该封装在某个地方,但具体位置由您决定
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
一种面向对象的方法。显然,match?
方法可以以最符合您需求的任何方式编写,也可以根据您的需求变化进行调整——我在这里使用了regex来帮助演示这种方法的灵活性。
方法的TYPES
常量和typeu应该封装在某个地方,但具体位置由您决定
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
我倾向于在自己的代码中使用类似的东西,只是因为我更愿意定义一个表,显示与匹配值和预期输出的关系:
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()
轻松初始化哈希常量:
---
? !ruby/regexp /\A[4-6]/
: B type
? !ruby/regexp /\A[0-3]/
: A type
? !ruby/regexp /\A[7-9]/
: C type
---
? !ruby/regexp/\A[4-6]/
:B型
? !ruby/regexp/\A[0-3]/
:A型
? !ruby/regexp/\A[7-9]/
:C类型
并通过一个简单的将HASH.to_yaml
放入创建
也就是说,我强烈支持使用case
语句方法。我倾向于在自己的代码中使用类似的东西,因为我更喜欢定义一个表,显示与匹配值和预期输出的关系:
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()
轻松初始化哈希常量:
---
? !ruby/regexp /\A[4-6]/
: B type
? !ruby/regexp /\A[0-3]/
: A type
? !ruby/regexp /\A[7-9]/
: C type
---
? !ruby/regexp/\A[4-6]/
:B型
? !ruby/regexp/\A[0-3]/
:A型
? !ruby/regexp/\A[7-9]/
:C类型
并通过一个简单的将HASH.to_yaml
放入创建
话虽如此,我还是强烈支持一种陈述的方式。谢谢你的回复。是,代码存储为字符串,因为实际上代码可能还包含字符,但第一个字符始终是数字。case语句实际上并没有满足我对“清洁”的要求,因为我认为if语句没有太大的改进。+1没有对类型和代码之间的关系做出超出问题中所述的假设。谢谢你的回答。是,代码存储为字符串,因为实际上代码可能还包含字符,但第一个字符始终是数字。case语句实际上并没有满足我对“干净”的渴望,因为我没有看到if语句有什么大的改进。+1没有对类型和代码之间的关系做出超出问题中所述的假设。这与其说是“设计”改进,不如说是“语法”改进(如果我们可以称之为改进)。无论如何,谢谢你的帮助。这与其说是“设计”的改进,不如说是“语法”的改进(如果我们可以称之为改进的话)。无论如何,感谢您的帮助。这会对代码和类型之间的关系做出可能不正确的假设。这会对代码和类型之间的关系做出可能不正确的假设。这属于。这已经是最简单的了。即使你想出了一些奇特的方法,当进入机器代码级别时,它仍然会做类似的事情。这已经是最简单的了。即使你想出了一些奇特的方法,当进入机器代码级别时,它仍然会做类似的事情。不过,对我来说,使用散列只对所有数据进行迭代(从不单独访问密钥)似乎很奇怪(不知道为什么)。我不认为这很奇怪,它只是对它使用散列,一种类型的数据到另一种类型的数据的映射。使用子数组也可以做类似的事情,但是=>
有助于直观地提醒我们,这两个数组是绑定在一起以维护代码的。+1我正在考虑用类似的方式回答。仅使用散列遍历所有散列(从不访问)