Документация для to_i
может немного вводить в заблуждение:
Возвращает результат интерпретации начальных символов в str как целочисленную базу base (между 2 и 36)
«интерпретация» не означает, что она пытается проанализировать различные числовые форматы (как Date.parse
для датыформаты).Это означает, что он ищет действительный целочисленный литерал в Ruby (в данной базе).Например:
1234. #=> 1234
'1234'.to_i #=> 1234
1_234. #=> 1234
'1_234'.to_i. #=> 1234
0d1234 #=> 1234
'0d1234'.to_i #=> 1234
0x04D2 #=> 1234
'0x04D2'.to_i(16) #=> 1234
Ваш ввод в целом, однако, не является допустимым целочисленным литералом: (Руби не нравится ,
)
980,323,344.00
# SyntaxError (syntax error, unexpected ',', expecting end-of-input)
# 980,323,344.00
# ^
Но это начинается с действительного целочисленного литерала.И вот тут вступает в игру второе предложение:
Посторонние символы после конца действительного числа игнорируются.
Таким образом, результат равен 980
-начальные символы, которые образуют действительное целое число, преобразуемое в целое число.
Если ваши строки всегда имеют этот формат, вы можете просто delete
запятые и ввести результат через to_i
, который будет игнорировать конечный .00
:
'980,323,344.00'.delete(',') #=> "980323344.00"
'980,323,344.00'.delete(',').to_i #=> 980323344
В противном случае вы можете использовать регулярное выражение для проверки его формата перед его преобразованием:
input = '980,323,344.00'
number = case input
when /\A\d{1,3}(,\d{3})*\.00\z/
input.delete(',').to_i
when /other format/
# other conversion
end
И если вы имеете дело сденежные значения, вам следует рассмотреть возможность использования гема money и его монетизации для анализа форматированных значений:
amount = Monetize.parse('980,323,344.00')
#=> #<Money fractional:98032334400 currency:USD>
amount.format
#=> "$980.323.344,00"
Обратите внимание, что для format
требуется i18n, поэтому приведенный выше пример может потребовать некоторой настройки.