Memeriksa apakah variabel bilangan bulat

137

Apakah Rails 3 atau Ruby memiliki cara bawaan untuk memeriksa apakah suatu variabel bilangan bulat?

Sebagai contoh,

1.is_an_int #=> true
"[email protected]".is_an_int #=> false?
AnApprentice
sumber
kemungkinan rangkap dari Apakah ruby ​​1.9.2 memiliki is_a? fungsi?
Andrew Grimm
1
Daripada peduli apakah suatu variabel bilangan bulat, Anda harus memeriksa untuk melihat apakah variabel merespons to_i. Itu bagian dari "mengetik bebek" Ruby: Jika itu bisa bertindak seperti bilangan bulat, perlakukan seperti itu.
the Tin Man
4
@ the Tin Man: Tidak sepenuhnya. "hello" .to_i mengembalikan 0 yang mungkin bukan yang Anda harapkan.
EinLama
1
@AnApprentice Untuk informasi Anda, kind_of?adalah alias untuk is_a?.
Jacob Relkin
3
@JacobRelkin is_a?sedikit berbeda; ia bertanya apakah objek turunan dari kelas tertentu; kind_of?bertanya apakah itu adalah turunan atau anak dari kelas tertentu. fido.is_a? Dogadalah benar; fido.kind_of? Animalbenar, misalnya.
Tom Harrison

Jawaban:

274

Anda dapat menggunakan is_a?metode ini

>> 1.is_a? Integer
=> true
>> "[email protected]".is_a? Integer
=> false
>> nil.is_a? Integer
=> false
mportiz08
sumber
2
Itu sangat keren. apakah itu berfungsi untuk memvalidasi alamat email?
AnApprentice
65
@AnApprentice Sejak kapan memvalidasi alamat email menjadi bagian dari pertanyaan?
Jacob Relkin
4
ini tidak akan berfungsi jika nomornya berupa string seperti "11111111"
Ricbermo
lihat di bawah Integer(obj) rescue false Ini tidak akan berfungsi untuk "1" jika Anda ingin memeriksa apakah itu akan dikonversi
mc.
4
@Ricbermo "1111111" adalah sebuah String. Sebuah String yang dapat dikonversi menjadi dan Integer.
Sqeaky
50

Jika Anda ingin tahu apakah suatu objek adalah Integer sesuatu atau sesuatu yang dapat secara bermakna dikonversi ke Integer (TIDAK termasuk hal-hal seperti "hello", yang to_iakan dikonversi menjadi 0):

result = Integer(obj) rescue false
Alex D
sumber
2
Mungkin saya hanya seorang noob, tetapi tweak ini akan membantu saya. result = Penyelamatan integer (obj) false.
John Curry
@ JohnCurry, silakan edit jawabannya jika Anda bisa memperbaikinya. Begitulah cara SO bekerja.
Alex D
2
Ya, itu ditolak. "Suntingan ini menyimpang dari maksud asli kiriman" Tapi bagaimanapun, terima kasih atas jawaban Anda, itu membantu saya memecahkan masalah saya!
John Curry
7
Integer ('08 ') akan gagal karena string yang ditafsirkan sebagai oktal, Integer ('08', 10) berfungsi dengan baik. Untuk berjaga-jaga.
Jong Bor Lee
1
Tidak yakin apakah Integer(2.5) => 2selalu konversi yang berarti.
mkataja
29

Gunakan ekspresi reguler pada string:

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

Jika Anda ingin memeriksa apakah suatu variabel berjenis tertentu, Anda cukup menggunakan kind_of?:

1.kind_of? Integer #true
(1.5).kind_of? Float #true
is_numeric? "545"  #true
is_numeric? "2aa"  #false
Jacob Relkin
sumber
Ini persis apa yang saya cari is_numeric?
workdreamer
Saya pikir ini dekat, tetapi tidak sepenuhnya benar. Misalnya, itu akan gagal untuk ".34". Masalahnya, saya pikir, adalah bahwa dalam \d+?yang ?menentukan pertandingan non-serakah, sedangkan Anda mungkin ingin pertandingan opsional. Mengubah \d+?untuk \d*memperbaikinya, tapi saya ingin menjalankannya melalui serangkaian tes untuk memastikan. Ini juga tidak akan cocok dengan notasi hex atau eksponensial, tapi saya yakin itu bagus untuk kasus penggunaan tertentu.
Jeff
1
Mengapa tidak hanya menggunakan regexp ini: \A\d+\z?
NARKOZ
1
Bandingkan dengan Integer(obj) rescue falsekode dari @ alex-d di bawah ini; regexp sulit dibaca dan tidak jelas maksudnya. Keduanya berfungsi, saya sampai pada pertanyaan ini dalam upaya untuk memperbaiki regexp yang dibangun dengan buruk yang tidak selalu berfungsi :-)
Tom Harrison
17

Jika Anda tidak yakin dengan jenis variabel (bisa berupa string karakter angka), katakan itu adalah nomor kartu kredit yang diteruskan ke params, jadi itu awalnya berupa string tetapi Anda ingin memastikannya tidak t memiliki karakter huruf apa pun di dalamnya, saya akan menggunakan metode ini:

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

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

@ Benny menunjukkan pengawasan terhadap metode ini, ingatlah ini:

is_number? "01" # false. oops!
kentang besar
sumber
terima kasih, kamu menyelamatkan hariku. Bagi siapa pun yang perlu memeriksa apakah itu mengambang atau tidak dapat berubah langsung obj.to_s == obj.to_f.to_sseperti dalam kasus saya.
ksugiarto
Edmund itu pintar! 🙌
siwalikm
Luar biasa, saya lebih suka ini daripada Integer ('123fh') dan pengecualian penyelamatan.
zw963
6

Anda bisa menggunakan triple sama dengan.

if Integer === 21 
    puts "21 is Integer"
end
Tsoodol
sumber
5

Ada var.is_a? Class(dalam kasus Anda:) var.is_a? Integer; yang mungkin sesuai dengan tagihan. Atau ada Integer(var), di mana ia akan melempar pengecualian jika tidak dapat menguraikannya.

Groxx
sumber
3

Cara yang lebih "mengetik bebek" adalah dengan menggunakan kelas respond_to?"seperti integer" atau "string-like" ini juga dapat digunakan

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

Jika Anda tidak perlu mengkonversi nilai nol, saya menemukan metode to_idan to_fmenjadi sangat berguna karena mereka akan mengkonversi string ke nilai nol (jika tidak dapat dikonversi atau nol) atau nilai aktual Integeratau 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: hati-hati, nilai 0integer bukan falsey itu benar ( !!0 #=> true) (terima kasih @prettycoder)

EDIT

Ah baru tahu tentang kasing hitam ... sepertinya hanya terjadi jika angkanya ada di posisi pertama

"12blah".to_i => 12
Cyril Duchon-Doris
sumber
0 benar di ruby!
prettycoder
1
@prettycoder terima kasih untuk kepala, saya akan segera memperbaikinya dalam jawaban
Cyril Duchon-Doris
1

Untuk memanfaatkan jawaban Alex D , gunakan penyempurnaan :

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

Kemudian, di kelas Anda:

require 'core_ext/string/integerable'

class MyClass
  using CoreExtensions::Integerable

  def method
    'my_string'.integer?
  end
end
Vadym Tyemirov
sumber
0

Saya memiliki masalah yang sama sebelum mencoba untuk menentukan apakah ada sesuatu yang berupa string atau nomor apa pun. Saya telah mencoba menggunakan ekspresi reguler, tetapi itu tidak dapat diandalkan untuk kasus penggunaan saya. Sebagai gantinya, Anda dapat memeriksa kelas variabel untuk melihat apakah itu adalah turunan dari kelas Numerik.

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

Dalam situasi ini, Anda juga bisa menggantikan keturunan Numeric: BigDecimal, Date :: Infinity, Integer, Fixnum, Float, Bignum, Rasional, Kompleks

penguincoder
sumber
-1

Mungkin Anda mencari sesuatu seperti ini:

Terima "2.0 atau 2.0 sebagai INT tetapi tolak 2.1 dan" 2.1 "

num = 2.0

jika num.is_a? String num = Float (num) menyelamatkan ujung yang salah

new_num = Penyelamatan integer (num) salah

menempatkan num

menempatkan new_num

menempatkan num == new_num

Owais Akbani
sumber