我想要一个类似to_numeric(str)的方法,它将数字字符串'str'转换为数字形式,否则返回nil。通过数字形式,如果string是整数方法,则应该返回整数,并且字符串在float中,它应该返回float。
我尝试使用以下代码。它工作正常但如果可能需要更好的解决方案。
def to_numeric(str)
Integer(str)
rescue
Float(str) if Float(str) rescue nil
end
我忘记提到的一件重要事情是“我不知道我输入的类型”。
我的用例:
arr = [1, 1.5, 2, 2.5, 4]
some_input = get_input_from_some_source
if arr.include?(to_numeric(some_input))
# do something
end
答案 0 :(得分:11)
您可以使用BigDecimal#frac
来实现您的目标
require 'bigdecimal'
def to_numeric(anything)
num = BigDecimal.new(anything.to_s)
if num.frac == 0
num.to_i
else
num.to_f
end
end
它可以处理
#floats
to_numeric(2.3) #=> 2.3
#rationals
to_numeric(0.2E-4) #=> 2.0e-05
#integers
to_numeric(1) #=> 1
#big decimals
to_numeric(BigDecimal.new("2"))
并且以字符串的形式浮动,有理数和整数
答案 1 :(得分:4)
使用String#to_f方法将其转换为Float
。由于使用duck typing的ruby,您可能不在乎它是Integer
。
如果它看起来像数字,像数字一样游动,像数字一样呱呱叫,那么它可能是数字。
但请注意! to_f
不会抛出任何例外:
"foobar".to_f # => 0
答案 2 :(得分:2)
如果你真的坚持区分Integer和Floats,那么你可以像这样实现to_numeric
:
def to_numeric(thing)
return thing.to_s.to_i if thing.to_s == thing.to_s.to_i.to_s
return thing.to_s.to_f if thing.to_s == thing.to_s.to_f.to_s
thing
end
它将一个对象转换为整数,如果它的字符串表示看起来像一个整数(与float相同),或者如果不是则返回未改变的东西:
['1', '1.5', 'foo', :bar, '2', '2.5', File].map {|obj| to_numeric obj}
# => [1, 1.5, "foo", :bar, 2, 2.5, File]
答案 3 :(得分:2)
以下是一些选项:
使用浮动进行比较:
arr = [1, 1.5, 2, 2.5, 4]
arr.include? "4.0".to_f #=> true
使用字符串进行比较:
arr = %w(1 1.5 2 2.5 4)
arr.include? "4" #=> true
使用eval
进行转换:
eval("4.0") #=> 4.0
eval("4") #=> 4
但是在使用eval
时你必须非常小心,请参阅@ tessi的评论。
答案 4 :(得分:0)
def to_numeric(str)
str.include?(".") ? str.to_f : str.to_i
end