Есть ли в Rails 3 или Ruby встроенный способ проверки, является ли переменная целым числом?
Например,
1.is_an_int #=> true
"dadadad@asdasd.net".is_an_int #=> false?
Есть ли в Rails 3 или Ruby встроенный способ проверки, является ли переменная целым числом?
Например,
1.is_an_int #=> true
"dadadad@asdasd.net".is_an_int #=> false?
to_i
. Это часть «утиной печати» Ruby: если она может действовать как целое число, относитесь к нему как к единице.
kind_of?
это псевдоним is_a?
.
is_a?
немного отличается; он спрашивает, принадлежит ли объект экземпляру определенного класса; kind_of?
спрашивает, является ли это экземпляром или дочерним элементом определенного класса. fido.is_a? Dog
правда; fido.kind_of? Animal
верно, например.
Ответы:
Вы можете использовать is_a?
метод
>> 1.is_a? Integer
=> true
>> "dadadad@asdasd.net".is_a? Integer
=> false
>> nil.is_a? Integer
=> false
Integer(obj) rescue false
Это не сработает для "1", если вы хотите проверить, конвертируется ли он
Если вы хотите знать, является ли объект объектом Integer
или чем-то, что можно значимо преобразовать в целое число (НЕ включая такие вещи, как "hello"
, которые to_i
будут преобразованы в 0
):
result = Integer(obj) rescue false
Integer(2.5) => 2
это всегда значимое преобразование.
Используйте регулярное выражение в строке:
def is_numeric?(obj)
obj.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
end
Если вы хотите проверить, имеет ли переменная определенный тип, вы можете просто использовать kind_of?
:
1.kind_of? Integer #true
(1.5).kind_of? Float #true
is_numeric? "545" #true
is_numeric? "2aa" #false
\d+?
том ?
специфицирует нежадное матч, в то время как вам , вероятно , хочет дополнительный матч. Изменение \d+?
на \d*
может исправить это, но я бы хотел провести его через набор тестов, чтобы убедиться. Это также не будет соответствовать шестнадцатеричной или экспоненциальной нотации, но я уверен, что это нормально для определенных случаев использования.
\A\d+\z
?
Integer(obj) rescue false
кодом из @ alex-d ниже; regexp трудно читать, и его назначение непонятно. Оба работают, я пришел к этому вопросу в попытке исправить плохо сконструированное регулярное выражение, которое не всегда работало :-)
Если вы не уверены в типе переменной (это может быть строка числовых символов), скажите, что это был номер кредитной карты, переданный в params, поэтому изначально это будет строка, но вы хотите убедиться, что это не так. Если в нем нет буквенных символов, я бы использовал этот метод:
def is_number?(obj)
obj.to_s == obj.to_i.to_s
end
is_number? "123fh" # false
is_number? "12345" # true
@Benny указывает на недосмотр этого метода, имейте это в виду:
is_number? "01" # false. oops!
obj.to_s == obj.to_f.to_s
так, как в моем случае.
Если вам не нужно преобразовывать нулевые значения, я считаю методы to_i
и to_f
чрезвычайно полезными, поскольку они преобразуют строку либо в нулевое значение (если не конвертируемое или нулевое), либо в фактическое Integer
или Float
значение.
"0014.56".to_i # => 14
"0014.56".to_f # => 14.56
"0.0".to_f # => 0.0
"not_an_int".to_f # 0
"not_a_float".to_f # 0.0
"0014.56".to_f ? "I'm a float" : "I'm not a float or the 0.0 float"
# => I'm a float
"not a float" ? "I'm a float" : "I'm not a float or the 0.0 float"
# => "I'm not a float or the 0.0 float"
EDIT2: будьте осторожны, 0
целочисленное значение не является ложным, это правда ( !!0 #=> true
) (спасибо @prettycoder)
РЕДАКТИРОВАТЬ
Ах, только что узнал о темных случаях ... кажется, что это происходит только в том случае, если номер находится на первой позиции, хотя
"12blah".to_i => 12
Чтобы извлечь выгоду из ответа Alex D , используя уточнения :
module CoreExtensions
module Integerable
refine String do
def integer?
Integer(self)
rescue ArgumentError
false
else
true
end
end
end
end
Позже в вашем классе:
require 'core_ext/string/integerable'
class MyClass
using CoreExtensions::Integerable
def method
'my_string'.integer?
end
end
У меня была аналогичная проблема, прежде чем я пытался определить, является ли что-то строкой или каким-либо числом. Я пробовал использовать регулярное выражение, но это ненадежно для моего варианта использования. Вместо этого вы можете проверить класс переменной, чтобы узнать, является ли она потомком класса Numeric.
if column.class < Numeric
number_to_currency(column)
else
column.html_safe
end
В этой ситуации вы также можете заменить любой из числовых потомков: BigDecimal, Date :: Infinity, Integer, Fixnum, Float, Bignum, Rational, Complex
Вероятно, вы ищете что-то вроде этого:
Принять "2.0 или 2.0 как INT, но отклонить 2.1 и 2.1"
число = 2,0
если num.is_a? String num = Float (num) спасает ложный конец
new_num = Целое число (число) спасение ложь
ставит число
помещает new_num
помещает num == new_num