Değişkenin bir tam sayı olup olmadığını kontrol etme


137

Rails 3 veya Ruby bir değişkenin tamsayı olup olmadığını kontrol etmenin yerleşik bir yolu var mı?

Örneğin,

1.is_an_int #=> true
"dadadad@asdasd.net".is_an_int #=> false?


1
Bir değişkenin tamsayı olup olmadığına bakmak yerine, değişkenin yanıt verip vermediğini kontrol etmelisiniz to_i. Bu Ruby'nin "ördek yazması" nın bir parçası: Eğer bir tamsayı gibi davranabiliyorsa, ona bir gibi davran.
Tin Man

4
Teneke Adam: Tamamen değil. "merhaba" .to_i 0 döndürür, beklediğiniz gibi olmayabilir.
EinLama

1
@AnApprentice Bilgileriniz için, kind_of?bir takma addır is_a?.
Jacob Relkin

3
@JacobRelkin is_a?biraz farklıdır; belirli bir sınıfın örneğinin nesnesinin olup olmadığını sorar; kind_of?belirli bir sınıfın örneği mi yoksa alt öğesi mi olduğunu sorar. fido.is_a? Dogdoğru; fido.kind_of? Animalörneğin doğrudur.
Tom Harrison

Yanıtlar:


274

is_a?Yöntemi kullanabilirsiniz

>> 1.is_a? Integer
=> true
>> "dadadad@asdasd.net".is_a? Integer
=> false
>> nil.is_a? Integer
=> false

2
Bu çok havalı. bu e-posta adreslerini doğrulamak için çalışıyor mu?
Ocak'ta

65
@AnApprentice E-posta doğrulaması ne zamandan beri sorunun bölümünün bir parçasıydı?
Jacob Relkin

4
"11111111" gibi bir dize gelirse bu işe yaramaz
Ricbermo

aşağıya bakın Integer(obj) rescue false Eğer dönüştürülüp dönüştürülmeyeceğini kontrol etmek istiyorsanız bu "1" için çalışmaz
mc.

4
@Ricbermo "1111111" bir dizedir. Dönüştürülebilir olan bir Dize ve Tamsayı.
Sqeaky

50

Eğer bir nesne bir olup olmadığını öğrenmek istiyorsanız Integer anlamlı bir tamsayı dönüştürülebilir ya da bir şey (gibi şeyleri de içeren DEĞİL "hello", hangi to_idönüşecektir 0):

result = Integer(obj) rescue false

2
Belki ben sadece bir çaylağım ama bu ince ayar bana yardım ederdi. sonuç = Tamsayı (obj) kurtarma yanlış.
John Curry

@JohnCurry, eğer cevabı geliştirebilirseniz düzenlemekten çekinmeyin. SO böyle çalışır.
Alex D

2
Yaptım, reddedildi. "Bu düzenleme yazının orijinal amacından sapıyor" Ama ne olursa olsun, cevabınız için teşekkür ederim, sorunumu çözmeme yardımcı oldu!
John Curry

7
Dize sekizlik olarak yorumlandığından tamsayı ('08 ') başarısız olur, Tamsayı ('08', 10) iyi çalışır. Her ihtimale karşı.
Jong Bor Lee

1
Her Integer(2.5) => 2zaman anlamlı bir dönüşüm olup olmadığından emin değilim .
mkataja

29

Bir dizede normal bir ifade kullanın:

def is_numeric?(obj) 
   obj.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
end

Bir değişkenin belirli türde olup olmadığını kontrol etmek istiyorsanız, şunu kullanabilirsiniz kind_of?:

1.kind_of? Integer #true
(1.5).kind_of? Float #true
is_numeric? "545"  #true
is_numeric? "2aa"  #false

Bu tam olarak is_numeric ne aradığını oldu?
workdreamer

Bunun yakın olduğunu düşünüyorum ama tam olarak doğru değil. Örneğin, ".34" için başarısız olur. Sorun, bence, içinde olmasıdır belirttiğinden olmayan açgözlü maç, sana oysa muhtemelen opsiyonel maç istiyoruz. Bunu değiştirmek için düzeltmek olabilir, ama emin olmak için bir test paketi ile çalıştırmak istiyorum. Bu ayrıca onaltılık veya üstel gösterimle eşleşmez, ancak eminim bazı kullanım durumları için iyi. \d+??\d+?\d*
Jeff

1
Neden sadece bu normal ifadeyi kullanmıyorsunuz \A\d+\z?
NARKOZ

1
Integer(obj) rescue falseAşağıdaki @ alex-d koduyla karşılaştırın ; regexp'nin okunması zordur ve niyetinde net değildir. Her iki işte de, her zaman işe yaramayan kötü yapılandırılmış bir regexp'i düzeltmek için bu soruya geldim :-)
Tom Harrison

17

Değişkenin türünden emin değilseniz (sayı karakterlerinden oluşan bir dize olabilir), parametrelere geçirilen bir kredi kartı numarası olduğunu söyleyin, bu yüzden aslında bir dize olur, ancak t herhangi bir harf karakter var, ben bu yöntemi kullanmak istiyorum:

    def is_number?(obj)
        obj.to_s == obj.to_i.to_s
    end

    is_number? "123fh" # false
    is_number? "12345" # true

@Benny bu yöntemin bir gözetimine dikkat çeker, bunu aklınızda bulundurun:

is_number? "01" # false. oops!

teşekkürler, günümü kurtarıyorsun. Kayan olup olmadığını kontrol etmesi gereken herkes için doğrudan obj.to_s == obj.to_f.to_sbenim durumumdaki gibi değişebilir .
ksugiarto

Edmund bu çok akıllıca! 🙌
siwalikm

Harika, ben tamsayı ('123fh') ve kurtarma istisnası tercih ederim.
zw963

6

Üçlü eşit kullanabilirsiniz.

if Integer === 21 
    puts "21 is Integer"
end

5

Var var.is_a? Class(senin durumunda:) var.is_a? Integer; bu faturaya uygun olabilir. Ya da Integer(var)ayrıştırılamazsa istisna atacağı yer de vardır.


3

"Ördek yazmanın" bir başka respond_to?yolu da "integer-like" veya "string-like" sınıfları da kullanılabilir.

if(s.respond_to?(:match) && s.match(".com")){
  puts "It's a .com"
else
  puts "It's not"
end

2

Sıfır değerlerini dönüştürmeniz gerekmiyorsa, yöntemleri bulur to_ive to_fson derece yararlı olur, çünkü dizeyi sıfır değerine (dönüştürülebilir veya sıfır değilse) veya gerçek Integerveya Floatdeğere dönüştürürler.

"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: dikkatli olun, 0tam sayı değeri doğru değil falsey ( !!0 #=> true) (teşekkürler @prettycoder)

DÜZENLE

Ah karanlık vakaları öğrendim ... ancak sayı ilk sıradaysa ortaya çıkıyor

"12blah".to_i => 12

0 yakutta doğrudur!
prettycoder

1
@prettycoder kafa kafaları için teşekkürler, bunu hemen cevaplayacağım
Cyril Duchon-Doris

1

Ayrıntıları kullanarak Alex D'nin cevabından yararlanmak için :

module CoreExtensions
  module Integerable
    refine String do
      def integer?
        Integer(self)
      rescue ArgumentError
        false
      else
        true
      end
    end
  end
end

Daha sonra, sınıfınızda:

require 'core_ext/string/integerable'

class MyClass
  using CoreExtensions::Integerable

  def method
    'my_string'.integer?
  end
end

0

Ben bir şey bir dize veya herhangi bir sayı herhangi bir sayı olup olmadığını belirlemeye çalışmadan önce benzer bir sorun vardı. Düzenli bir ifade kullanmayı denedim, ancak bu benim kullanım durumum için güvenilir değil. Bunun yerine, Sayısal sınıfın soyundan olup olmadığını görmek için değişkenin sınıfını denetleyebilirsiniz.

if column.class < Numeric
  number_to_currency(column)
else
  column.html_safe
end

Bu durumda, Sayısal torunların herhangi birinin yerine de kullanabilirsiniz: BigDecimal, Date :: Infinity, Integer, Fixnum, Float, Bignum, Rational, Complex


-1

Muhtemelen böyle bir şey arıyorsunuz:

"2.0 veya 2.0'ı INT olarak kabul et, ancak 2.1 ve" 2.1 "i reddet

num = 2.0

num.is_a ise? String num = Float (num) kurtarma yanlış sonu

new_num = Tamsayı (num) kurtarma yanlış

num koyar

yeni_sayı koyar

num == yeni_sayıyı koyar

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.