Saya memiliki yang berikut ini di pengontrol aplikasi saya:
def is_number?(object)
true if Float(object) rescue false
end
dan kondisi berikut di pengontrol saya:
if mystring.is_number?
end
Kondisinya menimbulkan undefined method
kesalahan. Saya kira saya telah mendefinisikan is_number
di tempat yang salah ...?
ruby-on-rails
ruby
string
integer
Jamie Buchanan
sumber
sumber
Jawaban:
Buat
is_number?
Metode.Buat metode pembantu:
Dan kemudian menyebutnya seperti ini:
Memperpanjang
String
Kelas.Jika Anda ingin dapat memanggil
is_number?
langsung pada string alih-alih meneruskannya sebagai param ke fungsi helper Anda, maka Anda perlu mendefinisikannyais_number?
sebagai ekstensiString
kelas, seperti:Dan kemudian Anda dapat menyebutnya dengan:
sumber
to_f
di atas, dan Float () tidak menunjukkan perilaku itu:Float("330.346.11")
menaikkanArgumentError: invalid value for Float(): "330.346.11"
lib/core_ext/string.rb
.is_number?(string)
bit berfungsi Ruby 1.9. Mungkin itu bagian dari Rails atau 1.8?String.is_a?(Numeric)
bekerja. Lihat juga stackoverflow.com/questions/2095493/… .Berikut ini patokan cara umum untuk mengatasi masalah ini. Perhatikan mana yang harus Anda gunakan mungkin bergantung pada rasio kasus palsu yang diharapkan.
Jika kinerja tidak penting, gunakan apa yang Anda suka. :-)
Detail pengecekan bilangan bulat:
Rincian pemeriksaan float:
sumber
sumber
/^\d+$/
bukan regexp yang aman di Ruby/\A\d+\Z/
. (misalnya "42 \ nbeberapa teks" akan kembalitrue
)/^\d+$/
jika berurusan dengan baris tetapi dalam kasus ini tentang awal dan akhir string/\A\d+\Z/
.Mengandalkan pengecualian yang dimunculkan bukanlah solusi tercepat, terbaca, atau andal.
Saya akan melakukan hal berikut:
sumber
expect(my_string).to match(/^[0-9]+$/)
my_string =~ /\A-?(\d+)?\.?\d+\Z/
ini memungkinkan Anda melakukan '.1', '-0.1', atau '12' tetapi tidak '' atau '-' atau '.'Pada Ruby 2.6.0, metode-cor numerik memiliki
exception
argumen- opsional [1] . Ini memungkinkan kami untuk menggunakan metode bawaan tanpa menggunakan pengecualian sebagai aliran kontrol:Oleh karena itu, Anda tidak harus menentukan metode Anda sendiri, tetapi dapat langsung memeriksa variabel seperti mis
sumber
begitulah cara saya melakukannya, tetapi saya pikir juga pasti ada cara yang lebih baik
sumber
object = "1.2e+35"; object.to_f.to_s == object
dan berhasiltidak, Anda hanya salah menggunakannya. is_number Anda? bertengkar. Anda menyebutnya tanpa argumen
Anda harus melakukan is_number? (mystring)
sumber
mystring
memang sebuah String,mystring.is_a?(Integer)
akan selalu salah. Sepertinya dia menginginkan hasil sepertiis_number?("12.4") #=> true
Tl; dr: Gunakan pendekatan regex. Ini 39x lebih cepat daripada pendekatan penyelamatan dalam jawaban yang diterima dan juga menangani kasus seperti "1.000"
-
Jawaban yang diterima oleh @Jakob S berfungsi untuk sebagian besar, tetapi menangkap pengecualian bisa sangat lambat. Selain itu, pendekatan penyelamatan gagal pada string seperti "1.000".
Mari tentukan metode:
Dan sekarang beberapa kasus uji:
Dan sedikit kode untuk menjalankan kasus uji:
Berikut adalah hasil dari test case:
Saatnya melakukan beberapa tolok ukur kinerja:
Dan hasilnya:
sumber
5.4e-29
. Saya rasa regex Anda dapat disesuaikan untuk menerima itu juga.Di rel 4, Anda perlu memasukkan
require File.expand_path('../../lib', __FILE__) + '/ext/string'
config / application.rb Andasumber
Jika Anda memilih untuk tidak menggunakan pengecualian sebagai bagian dari logika, Anda dapat mencoba ini:
Atau, jika Anda ingin itu bekerja di semua kelas objek, ganti
class String
denganclass Object
self convert to a string:!!(self.to_s =~ /^-?\d+(\.\d*)?$/)
sumber
nil?
nol adalah benar pada ruby, jadi Anda bisa melakukannya!!(self =~ /^-?\d+(\.\d*)?$/)
!!
pasti berhasil. Setidaknya satu panduan gaya Ruby ( github.com/bbatsov/ruby-style-guide ) menyarankan menghindari!!
demi.nil?
keterbacaan, tetapi saya telah melihat!!
digunakan di repositori populer, dan saya pikir ini adalah cara yang bagus untuk mengonversi ke boolean. Saya sudah mengedit jawabannya.gunakan fungsi berikut:
begitu,
is_numeric? "1.2f"
= salahis_numeric? "1.2"
= benaris_numeric? "12f"
= salahis_numeric? "12"
= benarsumber
"0"
. Perhatikan juga bahwa metode.try
ini bukan bagian dari pustaka inti Ruby dan hanya tersedia jika Anda menyertakan ActiveSupport."12"
, jadi contoh keempat Anda dalam pertanyaan ini salah."12.10"
dan"12.00"
gagal juga.Seberapa bodoh solusi ini?
sumber