Ich habe einen Wert, der eines von vier Dingen sein wird: boolean true, boolean false, die Zeichenfolge "true" oder die Zeichenfolge "false". Ich möchte den String in einen Booleschen Wert konvertieren, wenn es sich um einen String handelt, andernfalls möchte ich ihn unverändert lassen. Mit anderen Worten:
"wahr" sollte wahr werden
"falsch" sollte falsch werden
wahr sollte wahr bleiben
false sollte false bleiben
ruby
string
boolean
type-conversion
Schmirgel
quelle
quelle
true
oder ,false
oder ist es ausreichend , wenn das Ergebnis truthy oder Falsey ist? Wenn letzteresfalse
bereits falsch ist und beidetrue
und'true'
wahr sind, so ist der einzige Wert, für den das Ergebnis nicht bereits korrekt ist ,'false'
:if input == 'false' then true else input end
sollte es tun.!!(if input == 'false' then true else input end)
. Der zweite!
konvertiert den Rückgabewert in einen Booleschen Wert, der das Gegenteil von dem ist, was Sie wollen. der erste nimmt!
dann die Korrektur vor. Dieser "Trick" gibt es schon lange. Nicht jeder mag es.Antworten:
quelle
obj.to_s.downcase == 'true'
downcase!
Sie und Sie weisen 1 Objekt weniger zu.downcase
dupliziert die vorhandene Zeichenfolge. Wenn Frozen String Literals zu einer Ruby-Standardoption wird, ist dies weniger wichtig.Wenn Sie Rails 5 verwenden, können Sie dies tun
ActiveModel::Type::Boolean.new.cast(value)
.Verwenden Sie in Rails 4.2
ActiveRecord::Type::Boolean.new.type_cast_from_user(value)
.Das Verhalten unterscheidet sich geringfügig, da in Rails 4.2 der wahre und der falsche Wert überprüft werden. In Rails 5 werden nur falsche Werte überprüft. Sofern die Werte nicht Null sind oder mit einem falschen Wert übereinstimmen, wird angenommen, dass sie wahr sind. Falsche Werte sind in beiden Versionen gleich:
FALSE_VALUES = [false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"]
Rails 5 Quelle: https://github.com/rails/rails/blob/5-1-stable/activemodel/lib/active_model/type/boolean.rb
quelle
FALSE_VALUES
in Rails auch "no" enthält.ActiveRecord::Type::Boolean::FALSE_VALUES << "no"
einen Initialisierer hinzu.ActiveModel::Type::Boolean.new.cast(value)
Groß- und Kleinschreibung unterschieden wird. Daher wird 'False' wie jede andere Zeichenfolge mit Ausnahme von 'false' als wahr ausgewertet. leere Zeichenfolgen sind''
standardmäßig null und nicht falsch. ^^ wertvolle Einblicke hier von @thomasfedb über die Anpassung des InitialisierersActiveModel::Type::Boolean.new.cast(nil)
kehrt auch zurücknil
.ActiveRecord::Type::Boolean::FALSE_VALUES
eingefroren ist.Ich habe dieses Muster häufig verwendet, um das Kernverhalten von Ruby zu erweitern und die Konvertierung beliebiger Datentypen in boolesche Werte zu vereinfachen, wodurch es wirklich einfach ist, mit unterschiedlichen URL-Parametern usw. umzugehen.
Nehmen wir also an, Sie haben einen Parameter,
foo
der sein kann:Anstatt eine Reihe von Bedingungen zu verwenden, können Sie einfach anrufen
foo.to_boolean
und es wird den Rest der Magie für Sie erledigen.In Rails füge ich dies einem Initialisierer hinzu, der
core_ext.rb
in fast allen meinen Projekten benannt ist, da dieses Muster so häufig vorkommt.quelle
"buy"=~/b/ => 0
Aber("buy"=~/b/).to_boolean => false
Denk nicht zu viel nach:
So,
Sie können auch ".downcase" hinzufügen, wenn Sie sich Sorgen um Großbuchstaben machen.
quelle
nil.to_s == 'true' #false
quelle
value.to_s == 'true' ? true : false
if true then true, if false then false
was? Sie können es vollständig entfernen!value.to_s == 'true' ? true : false
sollte nur seinvalue.to_s == 'true'
quelle
In einer Rails 5.1-App verwende ich diese Kernerweiterung, auf der aufgebaut ist
ActiveRecord::Type::Boolean
. Es funktioniert perfekt für mich, wenn ich Boolesche Werte aus JSON-Zeichenfolgen deserialisiere.https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html
Initialisieren Sie die Kernerweiterungen
rspec
quelle
In Rails bevorzuge ich die Verwendung,
ActiveModel::Type::Boolean.new.cast(value)
wie in anderen Antworten hier erwähntAber wenn ich einfach Ruby lib schreibe. dann benutze ich einen Hack, bei dem
JSON.parse
(Standard-Ruby-Bibliothek) die Zeichenfolge "true" intrue
und "false" in konvertiertfalse
. Z.B:Beispiel aus einer Live-Anwendung:
quelle
Arbeiten in Schienen 5
quelle
ActiveModel::Type::Boolean.new.cast("False") # => true
... Die Verwendung von to_s.downcase für Ihre Eingabe ist eine gute IdeeIch habe einen kleinen Hack für diesen.
JSON.parse('false')
wird zurückkehrenfalse
undJSON.parse('true')
wird true zurückgeben. Aber das funktioniert nicht mitJSON.parse(true || false)
. Wenn Sie also so etwas verwendenJSON.parse(your_value.to_s)
, sollten Sie Ihr Ziel auf einfache, aber hackige Weise erreichen.quelle
Ein Edelstein wie https://rubygems.org/gems/to_bool kann verwendet werden, aber es kann leicht mit einem regulären Ausdruck oder einem ternären Text in einer Zeile geschrieben werden.
Regex-Beispiel:
ternäres Beispiel:
Der Vorteil der Regex-Methode besteht darin, dass reguläre Ausdrücke flexibel sind und einer Vielzahl von Mustern entsprechen können. Wenn Sie beispielsweise den Verdacht haben, dass var "True", "False", "T", "F", "t" oder "f" sein könnte, können Sie den regulären Ausdruck ändern:
quelle
\A
/\z
ist Anfang / Ende der Zeichenfolge und^
/$
ist Anfang / Ende der Zeile. Also wennvar == "true\nwhatevs"
dannboolean == true
.var.eql?('true') ? true : false
sehr geholfen und ich mag es sehr. Vielen Dank!Obwohl ich den Hash-Ansatz mag (ich habe ihn in der Vergangenheit für ähnliche Dinge verwendet), können Sie, da alles andere falsch ist, überprüfen, ob er in ein Array aufgenommen wurde:
oder wenn andere Werte als wahr angesehen werden könnten:
Sie
value
müssten andere Dinge tun, wenn Ihr Original ein gemischter Fall wäre:Für Ihre spezifische Beschreibung Ihres Problems könnten Sie jedoch das letzte Beispiel als Lösung verwenden.
quelle
In Schienen habe ich vorher so etwas gemacht:
Das ist schön, wenn Sie versuchen, Ihre booleschen Zeichenfolgenvergleiche auf dieselbe Weise abzugleichen, wie dies bei Rails für Ihre Datenbank der Fall wäre.
quelle
Nahe an dem, was bereits gepostet wurde, aber ohne den redundanten Parameter:
Verwendung:
quelle