属性としてコードを持つ製品クラスがあります。コードは常に数字であり、最初の桁に基づいて製品は特定のタイプです。
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'
if
3 分岐ステートメントを使用せずに製品タイプを判別する方法を探しています。
何か案は?
属性としてコードを持つ製品クラスがあります。コードは常に数字であり、最初の桁に基づいて製品は特定のタイプです。
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'
if
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
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 では、それがリテラル整数の場合、数値が 8 進数に変換されます。それが誤った仮定である場合は、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/regexp /\A[4-6]/ :Bタイプ ? !ruby/regexp /\A[0-3]/ :Aタイプ ? !ruby/regexp /\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" : ""