Преобразуйте входное значение в целое число или число с плавающей запятой, в зависимости от ситуации, используя Ruby - PullRequest
5 голосов
/ 10 ноября 2011

Полагаю, у меня есть хороший ответ на этот вопрос, но я хотел убедиться, что у ruby-philes нет лучшего способа сделать это.

Обычно, учитывая входную строку, я хотел бы преобразовать строку в целое число, где это уместно, или число с плавающей запятой, где это необходимо. В противном случае просто верните строку.

Я опубликую свой ответ ниже, но я хотел бы знать, есть ли лучший выход там.

Ex:

to_f_or_i_or_s("0523.49") #=> 523.49
to_f_or_i_or_s("0000029") #=> 29
to_f_or_i_or_s("kittens") #=> "kittens"

Ответы [ 6 ]

9 голосов
/ 10 ноября 2011

Я бы по возможности избегал использования регулярных выражений в Ruby.Известно, что это медленно

5 голосов
/ 10 ноября 2011
def to_f_or_i_or_s(v)
    v.match('\.').nil? ? Integer(v) : Float(v) rescue v.to_s
end
2 голосов
/ 16 июня 2013

Зависит от требований безопасности.

def to_f_or_i_or_s s
    eval(s) rescue s
end
2 голосов
/ 10 ноября 2011

Куча регулярных выражений может быть хорошей идеей, если вы хотите обрабатывать числа в научной нотации (что делает String#to_f):

def to_f_or_i_or_s(v)
    case(v)
    when /\A\s*[+-]?\d+\.\d+\z/
        v.to_f
    when /\A\s*[+-]?\d+(\.\d+)?[eE]\d+\z/
        v.to_f
    when /\A\s*[+-]?\d+\z/ 
        v.to_i     
    else  
        v
    end
end

Вы можете объединить оба to_f дел в одно регулярное выражение, если хотите.

Это, конечно, приведет к ошибке при вводе '3,14159' в локали, в которой в качестве десятичного разделителя используется запятая.

0 голосов
/ 10 ноября 2016

CSV имеет конвертеры, которые делают это.

require "csv"
strings = ["0523.49", "29","kittens"]
strings.each{|s|p s.parse_csv(converters: :numeric).first}

#523.49
#29
#"kittens"

Однако по какой-то причине он конвертирует «00029» в число с плавающей точкой.

0 голосов
/ 10 ноября 2016

Я использовал этот метод

  def to_f_or_i_or_s(value)
    return value if value[/[a-zA-Z]/]

    i = value.to_i
    f = value.to_f

    i == f ? i : f
  end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...