ローマ字から整数へのリファクタリング
概要
私はローマ数字をその整数に変換するメソッド roman_to_integer(roman_string) を書いています: ‘IV’ を 4、‘XVI’ を 16 などに変換します。
ROMAN_TO_INT = {
"I" => 1,
"IV" => 4,
"V" => 5,
"IX" => 9,
"X" => 10,
"XL" => 40,
"L" => 50,
"XC" => 90,
"C" => 100,
"CD" => 400,
"D" => 500,
"CM" => 900,
"M" => 1000
}
def roman_to_integer(roman_string)
# TODO: translate roman string to integer
number = 0
str = roman_string.dup
until str.size.zero?
last_two_characters = str.slice(-2, 2)
if ROMAN_TO_INT.key?(last_two_characters)
number += ROMAN_TO_INT[last_two_characters]
str.chop!
else
number += ROMAN_TO_INT[str.slice(-1)]
end
str.chop!
end
number
end
メソッドを短くするにはどうすればよいですか? Rubocop では 10 行しか許可されません。頑張っているのですが、いつも最低13で終わってしまいました。
解決策
iGian と同じトリックを使用したさらに小さいバージョン:
ROMAN_TO_INT =
{
i: 1,
v: 5,
x: 10,
l: 50,
c: 100,
d: 500,
m: 1000
}
def roman_to_int(roman)
numbers = roman.downcase.chars.map { |char| ROMAN_TO_INT[char.to_sym] }.reverse
numbers.inject([0, 1]) do |result_number, int|
result, number = result_number
int >= number ? [result + int, int] : [result - int, number]
end.first
end