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
"dadadad@asdasd.net".is_an_int #=> false?


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
>> "dadadad@asdasd.net".is_a? Integer
=> false
>> nil.is_a? Integer
=> false

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

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

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!

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

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.


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

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

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

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


-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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.