it-swarm.com.de

Ruby: Wie konvertiert man einen String in Boolean?

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 Boolean konvertieren, wenn er ein String ist, ansonsten unverändert lassen. Mit anderen Worten:

"true" sollte wahr werden

"falsch" sollte falsch werden

wahr sollte wahr bleiben

false sollte falsch bleiben

62
emery
def true?(obj)
  obj.to_s == "true"
end
94
steenslag

Wenn Sie Rails 5 verwenden, können Sie ActiveModel::Type::Boolean.new.cast(value) ausführen.

Verwenden Sie in Rails 4.2 ActiveRecord::Type::Boolean.new.type_cast_from_user(value).

Das Verhalten ist etwas anders, da in Rails 4.2 der wahre Wert und der falsche Wert geprüft werden. In Rails 5 werden nur falsche Werte geprüft. Wenn die Werte nicht gleich Null sind oder mit einem falschen Wert übereinstimmen, wird davon ausgegangen, dass sie wahr sind. Falsche Werte sind in beiden Versionen gleich: FALSE_VALUES = [false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"]

Schienen 5 Quelle: https://github.com/Rails/rails/blob/5-1-stable/activemodel/lib/active_model/type/boolean.rb

65
rado
if value.to_s == 'true'
  true
elsif value.to_s == 'false'
  false
end
15
archana

Ich habe dieses Muster häufig verwendet, um das Kernverhalten von Ruby zu erweitern, um die Konvertierung beliebiger Datentypen in boolesche Werte zu vereinfachen, wodurch der Umgang mit unterschiedlichen URL-Parametern usw. sehr einfach ist.

class String
  def to_boolean
    ActiveRecord::Type::Boolean.new.cast(self)
  end
end

class NilClass
  def to_boolean
    false
  end
end

class TrueClass
  def to_boolean
    true
  end

  def to_i
    1
  end
end

class FalseClass
  def to_boolean
    false
  end

  def to_i
    0
  end
end

class Integer
  def to_boolean
    to_s.to_boolean
  end
end

Nehmen wir an, Sie haben einen Parameter foo, der sein kann:

  • eine ganze Zahl (0 ist falsch, alle anderen sind wahr)
  • ein wahrer Boolean (wahr/falsch) 
  • eine Zeichenfolge ("true", "false", "0", "1", "TRUE", "FALSE")
  • null

Anstatt eine Reihe von Bedingungen zu verwenden, können Sie einfach foo.to_boolean aufrufen und der Rest der Magie wird für Sie erledigt.

In Rails füge ich dies in fast allen meinen Projekten zu einem Initialisierer namens core_ext.rb hinzu, da dieses Muster so üblich ist.

## EXAMPLES

nil.to_boolean     == false
true.to_boolean    == true
false.to_boolean   == false
0.to_boolean       == false
1.to_boolean       == true
99.to_boolean      == true
"true".to_boolean  == true
"foo".to_boolean   == true
"false".to_boolean == false
"TRUE".to_boolean  == true
"FALSE".to_boolean == false
"0".to_boolean     == false
"1".to_boolean     == true
true.to_i          == 1
false.to_i         == 0
14
Steve Craig
h = { "true"=>true, true=>true, "false"=>false, false=>false }

["true", true, "false", false].map { |e| h[e] }
  #=> [true, true, false, false] 
13
Cary Swoveland

Denken Sie nicht zu viel:

bool_or_string.to_s == "true"  

So,

"true".to_s == "true"   #true
"false".to_s == "true"  #false 
true.to_s == "true"     #true
false.to_s == "true"    #false

Sie können auch ".downcase" hinzufügen, wenn Sie sich Sorgen um Großbuchstaben machen.

11
David Foley

Obwohl ich den Hash-Ansatz mag (ich habe ihn in der Vergangenheit für ähnliche Sachen verwendet), da Sie nur wirklich auf die Übereinstimmung von Wahrheitswerten Wert legen - da alles andere falsch ist - können Sie die Aufnahme in ein Array überprüfen:

value = [true, 'true'].include?(value)

oder wenn andere Werte als wahr angesehen werden könnten:

value = [1, true, '1', 'true'].include?(value)

sie müssten anderes tun, wenn Ihre ursprüngliche value gemischt sein könnte:

value = value.to_s.downcase == 'true'

aber für Ihre spezifische Beschreibung Ihres Problems könnten Sie dieses letzte Beispiel als Lösung verwenden.

3
Pavling

Ich habe einen kleinen Hack für diesen einen. JSON.parse('false') gibt false zurück und JSON.parse('true') gibt true zurück. Das funktioniert aber nicht mit JSON.parse(true || false). Wenn Sie also etwas wie JSON.parse(your_value.to_s) verwenden, sollte dies Ihr Ziel auf einfache, aber harte Art erreichen. 

2
Felipe Funes

Ein Edelstein wie https://rubygems.org/gems/to_bool kann verwendet werden, er kann jedoch leicht in eine Zeile geschrieben werden, indem eine Regex oder ein Ternär verwendet wird.

regex-Beispiel:

boolean = (var.to_s =~ /^true$/i) == 0

ternäres Beispiel:

boolean = var.to_s.eql?('true') ? true : false

Der Vorteil der Regex-Methode besteht darin, dass reguläre Ausdrücke flexibel sind und einer Vielzahl von Mustern entsprechen. Wenn Sie beispielsweise den Verdacht haben, dass var "True", "False", 'T', 'F', 't' oder 'f' sein könnte, können Sie die Regex ändern:

boolean = (var.to_s =~ /^[Tt].*$/i) == 0
2
emery

In Rails habe ich vorher so etwas gemacht:

class ApplicationController < ActionController::Base
  # ...

  private def bool_from(value)
    !!ActiveRecord::Type::Boolean.new.type_cast_from_database(value)
  end
  helper_method :bool_from

  # ...
end

Was schön ist, wenn Sie versuchen, Ihre Vergleiche mit booleschen Strings auf dieselbe Weise abzugleichen, wie dies Rails für Ihre Datenbank tun würde.

1
Chad M

In Rails benutze ich ActiveModel::Type::Boolean.new.cast(value), wie in anderen Antworten hier erwähnt 

Aber wenn ich einfach nur Ruby lib schreibe. dann verwende ich einen Hack, bei dem JSON.parse (Standard-Ruby-Bibliothek) die Zeichenfolge "true" in "true" und "false" in "false" konvertiert. Z.B.:

require 'json'
Azure_cli_response = `az group exists --name derrentest`  # => "true\n"
JSON.parse(Azure_cli_response) # => true

Azure_cli_response = `az group exists --name derrentesttt`  # => "false\n"
JSON.parse(Azure_cli_response) # => false

Beispiel aus Live-Anwendung:

require 'json'
if JSON.parse(`az group exists --name derrentest`)
  `az group create --name derrentest --location uksouth`
end

bestätigt unter Ruby 2.5.1

0
equivalent8

In einer Rails 5.1-App verwende ich diese Kernerweiterung, die auf ActiveRecord::Type::Boolean aufgebaut ist. Es funktioniert perfekt für mich, wenn ich Boolean von JSON-String deserialisiere.

https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html

# app/lib/core_extensions/string.rb
module CoreExtensions
  module String
    def to_bool
      ActiveRecord::Type::Boolean.new.deserialize(downcase.strip)
    end
  end
end

core-Erweiterungen initialisieren

# config/initializers/core_extensions.rb
String.include CoreExtensions::String

rspec

# spec/lib/core_extensions/string_spec.rb
describe CoreExtensions::String do
  describe "#to_bool" do
    %w[0 f F false FALSE False off OFF Off].each do |falsey_string|
      it "converts #{falsey_string} to false" do
        expect(falsey_string.to_bool).to eq(false)
      end
    end
  end
end
0
mnishiguchi