2016-11-21 2 views
3

У меня есть текстовое поле, в котором пользователь может ввести число, и я хочу, чтобы иметь возможность преобразовать строку в целое число или поместить на основе ввода пользователя. Есть ли простой способ сделать это в Ruby?Как преобразовать строку в Integer или Float

Например:

User Input: "123" -> Output: 123 
User Input: "123.99" -> Output: 123.99 
+0

Вы хотите целое число для '' 123 '' и float для '' 123.99 "'? – Stefan

+1

Возможно, вы захотите посмотреть, почему вы хотите это сделать? Если присутствует float, их математика будет запускаться и возвращать float (например, '1/2' возвращает' 0', а '1.0/2' возвращает' 0.5'. Если причиной, по которой вы хотите иметь оба типа, является отображение целого числа в конце (например, так что пользователь не видит '1.0'), вы можете захотеть изучить метод, который отображает число, как ожидалось, и всегда конвертировать ваш вход в float. – AJFaraday

+0

Добро пожаловать в Stack Overflow. например, мы хотели бы видеть доказательства ваших усилий, обычно как минимальный код, демонстрирующий проблему, с которой вы столкнулись. Без этого похоже, что вы не пробовали, и вы хотите, чтобы мы решили проблему для вас ». [ask ] ", а связанные страницы и" [mcve] "идут в это, а также http://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow- –

ответ

-4

Вы можете сделать это следующим образом:

def to_float_or_int(string) 
    throw "error" unless string && string.length > 0 
    return string.to_f if string.include?('.') || string.include?(',') 
    string.to_i 
end 

Первая строка гарантирует, что вы всегда получите результат, основанный на вводе. Если вы удалите, что пустая строка будет давать 0 вместо ошибки.

+0

Как насчет 'to_float_or_int ('1a') # => 1' или' to_float_or_int ('') # => 0'? –

+0

Не нужно проверять запятую, так как вы все равно отбрасываете информацию: ''1,23'.to_f => 1' –

+0

Не все настройки LOCALE используют' .' в качестве дробного индикатора. В зависимости от того, где кто-то находится в мире, «1,23» будет уместным, а «1,23.to_f» будет эквивалентен «1,23» в США. –

3

Использование to_i или to_f на струне

irb(main):001:0> "13".to_i 
=> 13 
irb(main):002:0> "13".to_f 
=> 13.0 
-1

Я хотел бы использовать:

def convert(input) 
    [:Integer, :Float].each do |m| 
    begin 
     return Kernel.method(m).call(input) 
    rescue ArgumentError 
    end 
    end 
    nil 
end 

convert('') # => nil 
convert(' ') # => nil 
convert('1') # => 1 
convert('1.0') # => 1.0 
convert('.01') # => 0.01 

Как это работает?

Integer() и Float() методы в классе Kernel, так что

Kernel.method(m) 

возвращает объект метод, позволяющий call послать значение input к нему. Если это успешно, возвращается возвращаемое значение и цикл each завершается. Если он взрывает rescue ArgumentError, то он останавливается и цикл each продолжается. Если контур заканчивается без короткого замыкания на return, то nil возвращается Руби.

+0

Не слишком ли сложно? Не будет ли «Целое (вводное) спасение Float (input) rescue nil' просто сделать? –

+0

также 'convert (1.23)' возвращает '1', чего не ожидалось. –

+0

Inline 'rescue' не делает то же самое, что' rescue ArgumentError'. –

0

Если вы хотите не показывать десятичные знаки, когда ввод выглядит как целое, вы можете преобразовать свой ввод в Float и использовать '%g' для отображения номера.

Возможно, вы столкнулись с неожиданным поведением или должны написать некоторую логику, чтобы проверить, является ли ваш числовой объект Float или Integer иначе.

def display_number(input) 
    '%g' % Float(input) 
end 

puts display_number("1") 
puts display_number(2) 
puts display_number("1.23") 
puts display_number(2.3456) 
puts display_number(Math::PI) 
puts display_number("not a number") 

# => 1 
# 2 
# 1.23 
# 2.3456 
# 3.14159 
# convert_to_int_or_float.rb:2:in `Float': invalid value for Float(): "not a number" (ArgumentError) 
0

Это расширит строки с двумя новыми методами, но вы просто должны вызвать #to_numeric на любую строку, и она будет возвращать либо поплавок или Int соответственно.

class String 
    def numeric_string? 
    Float(self) != nil rescue false 
    end 

    def to_numeric 
    if self.numeric_string? 
     if self.index('.') 
     return self.to_f 
     else 
     return self.to_i 
     end 
    end 
    end 
end 

['2.0', '15', '4500.1234', '111.234'].each do |str| 
    puts str.to_numeric 
end 

# 2.0 
# 15 
# 4500.1234 
# 111.234 

Надеюсь, это поможет!

Смежные вопросы