Ich habe Folgendes in meinem Anwendungscontroller:
def is_number?(object)
true if Float(object) rescue false
end
und die folgende Bedingung in meinem Controller:
if mystring.is_number?
end
Die Bedingung löst einen undefined method
Fehler aus. Ich schätze, ich habe is_number
am falschen Ort definiert ...?
ruby-on-rails
ruby
string
integer
Jamie Buchanan
quelle
quelle
Antworten:
is_number?
Methode erstellen .Erstellen Sie eine Hilfsmethode:
Und dann nenne es so:
Extend
String
Klasse.Wenn Sie
is_number?
die Zeichenfolge direkt aufrufen möchten, anstatt sie als Parameter an Ihre Hilfsfunktion zu übergeben, müssen Sie sie wie folgtis_number?
als Erweiterung derString
Klasse definieren :Und dann können Sie es nennen mit:
quelle
to_f
oben, und Float () zeigt dieses Verhalten nicht:Float("330.346.11")
RaisesArgumentError: invalid value for Float(): "330.346.11"
lib/core_ext/string.rb
.is_number?(string)
Bit Ruby 1.9 funktioniert. Vielleicht ist das Teil von Rails oder 1.8?String.is_a?(Numeric)
funktioniert. Siehe auch stackoverflow.com/questions/2095493/… .Hier ist ein Benchmark für gängige Methoden zur Lösung dieses Problems. Beachten Sie, welche Sie wahrscheinlich verwenden sollten, hängt vom Verhältnis der erwarteten falschen Fälle ab.
Wenn die Leistung keine Rolle spielt, verwenden Sie, was Sie möchten. :-)
Details zur Ganzzahlprüfung:
Details zur Floatprüfung:
quelle
quelle
/^\d+$/
ist kein sicherer regulärer Ausdruck in Ruby/\A\d+\Z/
. (zB "42 \ nsome text" würde zurückkehrentrue
)/^\d+$/
wenn es sich um Zeilen handelt, aber in diesem Fall geht es also um den Anfang und das Ende eines Strings/\A\d+\Z/
.Sich auf die angesprochene Ausnahme zu verlassen, ist nicht die schnellste, lesbarste und zuverlässigste Lösung.
Ich würde folgendes tun:
quelle
expect(my_string).to match(/^[0-9]+$/)
my_string =~ /\A-?(\d+)?\.?\d+\Z/
Sie können '.1', '-0.1' oder '12' machen, aber nicht '' oder '-' oder '.'Ab Ruby 2.6.0 verfügen die numerischen Cast-Methoden über ein optionales
exception
Argument [1] . Dies ermöglicht es uns, die integrierten Methoden zu verwenden, ohne Ausnahmen als Kontrollfluss zu verwenden:Daher müssen Sie keine eigene Methode definieren, sondern können Variablen wie z
quelle
So mache ich das, aber ich denke auch, dass es einen besseren Weg geben muss
quelle
object = "1.2e+35"; object.to_f.to_s == object
und es funktionierteNein, du benutzt es einfach falsch. Ihre is_number? hat ein Argument. du hast es ohne das Argument genannt
du solltest is_number machen? (mystring)
quelle
mystring
es sich tatsächlich um einen String handelt, istmystring.is_a?(Integer)
dieser immer falsch. Es sieht so aus, als ob er ein Ergebnis wieis_number?("12.4") #=> true
Tl; dr: Verwenden Sie einen Regex-Ansatz. Es ist 39x schneller als der Rettungsansatz in der akzeptierten Antwort und behandelt auch Fälle wie "1.000".
- -
Die akzeptierte Antwort von @Jakob S funktioniert größtenteils, aber das Abfangen von Ausnahmen kann sehr langsam sein. Außerdem schlägt der Rettungsansatz bei einer Zeichenfolge wie "1.000" fehl.
Definieren wir die Methoden:
Und jetzt einige Testfälle:
Und ein kleiner Code zum Ausführen der Testfälle:
Hier ist die Ausgabe der Testfälle:
Zeit für einige Leistungsbenchmarks:
Und die Ergebnisse:
quelle
5.4e-29
. Ich denke, Ihre Regex könnte optimiert werden, um diese auch zu akzeptieren.In Rails 4 müssen Sie
require File.expand_path('../../lib', __FILE__) + '/ext/string'
Ihre config / application.rb eingebenquelle
Wenn Sie keine Ausnahmen als Teil der Logik verwenden möchten, können Sie Folgendes versuchen:
Wenn Sie möchten, dass es über alle Objektklassen hinweg funktioniert, ersetzen Sie es
class String
durchclass Object
ein konvertiertes Selbst in eine Zeichenfolge:!!(self.to_s =~ /^-?\d+(\.\d*)?$/)
quelle
nil?
Null zu tun, ist auf Rubin trurthy, also können Sie gerade tun!!(self =~ /^-?\d+(\.\d*)?$/)
!!
funktioniert sicherlich. Mindestens ein Ruby- Styleguide ( github.com/bbatsov/ruby-style-guide ) schlug vor, dies!!
aus Gründen der.nil?
Lesbarkeit zu vermeiden , aber ich habe!!
es in beliebten Repositorys verwendet gesehen, und ich denke, es ist eine gute Möglichkeit, in Boolesche Werte zu konvertieren. Ich habe die Antwort bearbeitet.Verwenden Sie die folgende Funktion:
so,
is_numeric? "1.2f"
= falschis_numeric? "1.2"
= wahris_numeric? "12f"
= falschis_numeric? "12"
= wahrquelle
"0"
. Beachten Sie außerdem, dass die Methode.try
nicht Teil der Ruby-Kernbibliothek ist und nur verfügbar ist, wenn Sie ActiveSupport einschließen."12"
, sodass Ihr viertes Beispiel in dieser Frage falsch ist."12.10"
und"12.00"
scheitern auch.Wie dumm ist diese Lösung?
quelle