Есть ли в Rails 3 или Ruby встроенный способ проверки, является ли переменная целым числом?
Например,
1.is_an_int #=> true
"dadadad@asdasd.net".is_an_int #=> false?
ruby
ruby-on-rails-3
AnApprentice
источник
источник
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
так, как в моем случае.Там
var.is_a? Class
(в вашем случае :)var.is_a? Integer
; это могло бы соответствовать всем требованиям. Или тамInteger(var)
, где он выдаст исключение, если не сможет его проанализировать.источник
Вы можете использовать тройное равенство.
if Integer === 21 puts "21 is Integer" end
источник
Более «утиный» способ - использовать
respond_to?
этот способ также можно использовать классы «целочисленные» или «строковые».if(s.respond_to?(:match) && s.match(".com")){ puts "It's a .com" else puts "It's not" end
источник
Если вам не нужно преобразовывать нулевые значения, я считаю методы
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"
источник