Saya butuh fungsi, is_an_integer
,, di mana
"12".is_an_integer?
mengembalikan true."blah".is_an_integer?
mengembalikan salah.
Bagaimana saya bisa melakukan ini di Ruby? Saya akan menulis regex tapi saya berasumsi ada pembantu untuk ini yang saya tidak sadari.
Jawaban:
Anda dapat menggunakan ekspresi reguler. Berikut adalah fungsi dengan saran @ janm.
Versi yang diedit sesuai dengan komentar dari @wich:
Jika Anda hanya perlu memeriksa angka positif
sumber
/regexp/ === self
alih-alih!!(self =~ /regexp/)
konstruk. Anda dapat menggunakan kelas karakter '\ d' alih-alih[0-9]
Nah, inilah cara mudah:
Saya tidak setuju dengan solusi yang memancing pengecualian untuk mengubah string - pengecualian tidak mengontrol aliran, dan Anda mungkin melakukannya dengan cara yang benar. Yang mengatakan, solusi saya di atas tidak berurusan dengan non-basis-10 integer. Jadi, inilah cara untuk dilakukan tanpa menggunakan pengecualian:
sumber
self.to_i.to_s == self
denganInteger self rescue false
?Anda dapat menggunakan
Integer(str)
dan melihat apakah itu memunculkan:Harus ditunjukkan bahwa walaupun ini mengembalikan true untuk
"01"
, itu tidak untuk"09"
, hanya karena09
tidak akan menjadi integer literal yang valid. Jika itu bukan perilaku yang Anda inginkan, Anda dapat menambahkan10
sebagai argumen keduaInteger
, sehingga angka selalu ditafsirkan sebagai basis 10.sumber
#to_i
terlalu rusak karena permisif.Integer()
adalah kanonik karena denganInteger ()
Anda tahu pasti bahwa apa pun yang dianggap Ruby sebagai integer literal akan diterima, dan yang lainnya akan ditolak. Menggandakan apa yang bahasa sudah berikan kepada Anda bisa dibilang bau kode yang lebih buruk daripada menggunakan pengecualian untuk kontrol.Anda dapat melakukan satu liner:
atau bahkan
Bergantung pada apa yang Anda coba lakukan, Anda juga dapat langsung menggunakan blok awal dengan klausa penyelamatan:
sumber
sumber
true
danfalse
tetapiMatchData
contoh dannil
!!
atau gunakanpresent?
jika Anda memerlukan boolean!!( "12".match /^(\d)+$/ )
atau"12".match(/^(\d)+$/).present?
(yang terakhir membutuhkan Rails / activesupport)Ruby 2.6.0 memungkinkan casting ke integer tanpa memunculkan exception , dan akan kembali
nil
jika cast gagal. Dan karenanil
sebagian besar berperilaku sepertifalse
di Ruby, Anda dapat dengan mudah memeriksa bilangan bulat seperti:sumber
is_
. Saya menemukan bahwa konyol pada metode tanda tanya, saya suka"04".integer?
jauh lebih baik daripada"foo".is_integer?
."01"
dan semacamnya.sumber
integer?("a string")
ftl.String#integer?
adalah jenis tambalan umum yang suka ditambahkan oleh setiap pembuat kode Ruby dan sepupu mereka ke bahasa tersebut, yang mengarah ke basis kode dengan tiga implementasi berbeda yang tidak kompatibel secara halus dan kerusakan yang tidak terduga. Saya belajar ini dengan cara yang sulit di proyek-proyek besar Ruby.Cara Terbaik dan Sederhana menggunakan
Float
Integer
juga baik tetapi akan kembali0
untukInteger nil
sumber
Saya lebih memilih:
config / initializers / string.rb
lalu:
atau periksa nomor telepon:
sumber
Cara yang lebih sederhana bisa
sumber
sumber
Secara pribadi saya suka pendekatan pengecualian meskipun saya akan membuatnya sedikit lebih singkat:
Namun, seperti yang telah dinyatakan orang lain, ini tidak berfungsi dengan string Oktal.
sumber
Ruby 2.4 memiliki
Regexp#match?
: (dengan a?
)Untuk versi Ruby yang lebih lama, ada
Regexp#===
. Dan meskipun penggunaan langsung dari operator kasus kesetaraan umumnya harus dihindari, itu terlihat sangat bersih di sini:sumber
Ini mungkin tidak cocok untuk semua kasus yang menggunakan:
mungkin juga dilakukan untuk beberapa.
Jika itu angka dan bukan 0 maka akan mengembalikan angka. Jika mengembalikan 0 itu adalah string atau 0.
sumber
"12blah".to_i => 12
. Ini mungkin menyebabkan beberapa masalah dalam skenario aneh.Inilah solusi saya:
Dan inilah cara kerjanya:
/^(\d)+$/
adalah ekspresi regex untuk menemukan digit dalam string apa pun. Anda dapat menguji ekspresi dan hasil regex Anda di http://rubular.com/ .IntegerRegex
untuk menghindari alokasi memori yang tidak perlu setiap kali kami menggunakannya dalam metode.integer?
adalah metode interogatif yang harus dikembalikantrue
ataufalse
.match
adalah metode pada string yang cocok dengan kejadian sesuai ekspresi regex yang diberikan dalam argumen dan mengembalikan nilai yang cocok ataunil
.!!
mengkonversi hasilmatch
metode menjadi boolean yang setara.String
kelas yang ada adalah monkey patching, yang tidak mengubah apa pun dalam fungsionalitas String yang ada, tetapi hanya menambahkan metode lain yang dinamaiinteger?
pada objek String apa pun.sumber
Memperluas jawaban @ rado di atas satu juga bisa menggunakan pernyataan ternary untuk memaksa kembalinya boolean benar atau salah tanpa menggunakan poni ganda. Memang, versi negasi logis ganda lebih singkat, tetapi mungkin lebih sulit dibaca untuk pendatang baru (seperti saya).
sumber
Untuk kasus yang lebih umum (termasuk angka dengan titik desimal), Anda dapat mencoba metode berikut:
Anda dapat menguji metode ini dalam sesi irb:
Untuk penjelasan rinci tentang regex yang terlibat di sini, lihat artikel blog ini :)
sumber
obj.is_a? String
karena String # to_s akan kembali dengan sendirinya, yang saya kira tidak memerlukan terlalu banyak pemrosesan dibandingkan dengan.is_a?
panggilan. Dengan cara ini, Anda hanya akan melakukan satu panggilan di baris ini alih-alih satu atau dua. Juga, Anda bisa memasukkan langsung!!
ke dalamnumber?
metode, karena dengan konvensi, nama metode yang diakhiri dengan?
seharusnya mengembalikan nilai boolean. Salam!Saya suka yang berikut, lurus ke depan:
Hati-hati:
sumber
Satu liner masuk
string.rb
sumber
Saya tidak yakin apakah ini ada ketika pertanyaan ini diajukan tetapi bagi siapa pun yang menemukan tulisan ini, cara paling sederhana adalah:
.is_a?
akan bekerja dengan objek apa pun.sumber
"12".is_an_integer? == true
"not12".is_an_integer? == false
12.is_an_integer? == true