Ruby:文字列をブール値に変換する方法


107

ブール値true、ブール値false、文字列「true」、または文字列「false」の4つのうちの1つになる値があります。文字列の場合は文字列をブール値に変換し、それ以外の場合は変更しないでください。言い換えると:

「真」は真になるべき

「false」はfalseになります

trueはtrueのままである必要があります

falseはfalseのままである必要があります


2
結果 2つの値のtrueいずれfalseかである必要がありますか、それとも結果が真実か偽りであれば十分ですか?後者の場合、falsefalseyすでにあり、両方true'true'truthyなので、結果はすでに正しいされていない唯一の値は、です'false'if input == 'false' then true else input endそれを行う必要があります。
イェルクWミッターク

これは素晴らしいコメントですJorgですが、一部のアプリケーションでは、真偽値ではなくブール値trueまたはfalseが必要であると思います。
エメリー、2016年

2
Emery、ブール値を返す必要がある場合は、@Jörgの式の前に2つの「nots」を付けることができます!!(if input == 'false' then true else input end)。2つ目!は、戻り値を必要なものと反対のブール値に変換します。最初に!修正を行います。この「トリック」はずっと前からあります。誰もがそれを好むわけではありません。
Cary Swoveland 16年

回答:


126
def true?(obj)
  obj.to_s.downcase == "true"
end

3
はい、@ null、to_sメソッドはブール値のtrueまたはfalseを「true」または「false」に変換し、元の文字列の場合は値を変更しません。これで、文字列として「true」または「false」のいずれかが確実になりました。文字列が「true」に等しいかどうかを==チェックするだけです。そうである場合、元の値はtrueまたは「true」でした。そうでない場合、元の値はfalse、 "false"、またはまったく関係のないものでした。
エメリー

8
文字列は/というタイトルupcasedすることができるので、downcasingは試合が保証されます:obj.to_s.downcase == 'true'
TDH

1
使用するdowncase!と、割り当てられるオブジェクトが1つ少なくなります。 downcase既存の文字列を複製します。Frozen String LiteralsがRubyのデフォルトオプションになると、これはそれほど問題になりません。
danielricecodes

私は答えを自由に編集して、小文字の提案を含めました!上記のコメントに従って。読み方はエレガントではありませんが、使用している変数の型がわからない場合は、堅牢性を高めることは決して悪いことではありません。
エメリー

不正なデータを入力してもエラーは報告されないため、エラー処理が必要な場合は優れたソリューションではありません
Toby 1 Kenobi

118

Rails 5を使用すれば、できますActiveModel::Type::Boolean.new.cast(value)

Rails 4.2では、を使用します ActiveRecord::Type::Boolean.new.type_cast_from_user(value)

Rails 4.2と同様に、動作は少し異なります。true値とfalse値がチェックされます。Rails 5では、false値のみがチェックされます。値がnilであるか、false値と一致しない限り、trueであると見なされます。False値は両方のバージョンで同じです: FALSE_VALUES = [false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"]

Rails 5ソース:https : //github.com/rails/rails/blob/5-1-stable/activemodel/lib/active_model/type/boolean.rb


1
これは役に立ちますがFALSE_VALUES、Rails のセットにも「no」が含まれていることを願っています。
pjrebsch 2017

3
@pjrebschアプリにパッチを適用するのはかなり簡単です。ActiveRecord::Type::Boolean::FALSE_VALUES << "no"初期化子に追加するだけです。
thomasfedb 2018

ActiveModel::Type::Boolean.new.cast(value)大文字と小文字が区別されることに注意してください...したがって、「False」は「false」を除く他の文字列と同様にtrueと評価されます。空の文字列の''デフォルトはfalseではなくnilです。^^イニシャライザのカスタマイズに関する@thomasfedbによってここに提供された貴重な洞察
frostini '

1
ActiveModel::Type::Boolean.new.cast(nil)も返しますnil
Nikolay D

1
Rails 5.2.4以降、@ thomasfedbによって提案された方法は、フリーズされているため機能しなくなりましActiveRecord::Type::Boolean::FALSE_VALUESた。
1

24

私はこのパターンを頻繁に使用してRubyのコア動作を拡張し、任意のデータ型をブール値に変換する処理を簡単にしました。これにより、さまざまなURLパラメータなどを簡単に処理できます。

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

したがって、次のようなパラメータfooがあるとします。

  • 整数(0は偽、その他はすべて真)
  • 真のブール(真/偽)
  • 文字列( "true"、 "false"、 "0"、 "1"、 "TRUE"、 "FALSE")
  • なし

一連の条件文を使用する代わりに、呼び出すだけでfoo.to_boolean、残りの魔法を実行できます。

Railsではcore_ext.rb、このパターンが非常に一般的であるため、ほぼすべてのプロジェクトで指定されている初期化子にこれを追加します。

## 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

「t」と「f」「T」と「F」、「y」と「n」、「Y」と「N」はどうですか?
MrMesees

これはうまくいきません。「購入」は「b」で始まりますか?"buy"=~/b/ => 0 しかし("buy"=~/b/).to_boolean => false
マルコス

23

あまり考えすぎないでください。

bool_or_string.to_s == "true"  

そう、

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

大文字が心配な場合は、「。downcase」を追加することもできます。


5
nil.to_s == 'true' #false
juliangonzalez

15
if value.to_s == 'true'
  true
elsif value.to_s == 'false'
  false
end

10
ワンライナーとしてのコードvalue.to_s == 'true' ? true : false
Sagar Pandya 2016年

20
@ sagarpandya82:絶対にそれをしないでください、それは条件演算子の目的を無効にします:if true then true, if false then false何を推測しますか?完全に外せます!value.to_s == 'true' ? true : falseちょうどでなければなりませんvalue.to_s == 'true'
エリックDuminil

4
@EricDuminilは完全に同意し、当時の新人エラー。
Sagar Pandya

2
これらのワンライナーが失敗することはなく、値が「true」でない限り常にfalseを返しますが、値を変換できない場合、この回答はnilを返します。どちらも有効なアプローチであり、さまざまな状況に対する正しい答えになるかもしれませんが、同じではありません。
Doodad

1
この場合、@ AndreFigueiredo三項演算子は何もしません。なしで試して、結果を比較してください。
Eric Duminil


7

Rails 5.1アプリでは、上に構築されたこのコア拡張を使用します ActiveRecord::Type::Boolean。JSON文字列からブール値を逆シリアル化すると、完全に機能します。

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

コア拡張を初期化する

# 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

これは完璧です。まさに私が探していたもの。
Doug

5

Railsでは私は ActiveModel::Type::Boolean.new.cast(value)、ここの他の回答で述べたようにです

しかし、私が単純なRuby libを書くとき。次に、JSON.parse(標準Rubyライブラリ)が文字列「true」をtrue「false」に変換するハックを使用 しfalseます。例えば:

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

ライブアプリケーションの例:

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

Ruby 2.5.1で確認済み


5

Rails 5での作業

ActiveModel::Type::Boolean.new.cast('t')     # => true
ActiveModel::Type::Boolean.new.cast('true')  # => true
ActiveModel::Type::Boolean.new.cast(true)    # => true
ActiveModel::Type::Boolean.new.cast('1')     # => true
ActiveModel::Type::Boolean.new.cast('f')     # => false
ActiveModel::Type::Boolean.new.cast('0')     # => false
ActiveModel::Type::Boolean.new.cast('false') # => false
ActiveModel::Type::Boolean.new.cast(false)   # => false
ActiveModel::Type::Boolean.new.cast(nil)     # => nil

1
ActiveModel::Type::Boolean.new.cast("False") # => true...入力にto_s.downcaseを使用することをお勧めします
Raphayol

4

これには少しハックがあります。JSON.parse('false')戻りfalseJSON.parse('true')trueを返します。しかし、これはでは機能しませんJSON.parse(true || false)。したがって、このようなものを使用するJSON.parse(your_value.to_s)と、シンプルだがハックな方法で目標を達成できるはずです。


3

https://rubygems.org/gems/to_boolのような宝石使用できますが、正規表現または三項を使用して1行で簡単に書くことができます。

正規表現の例:

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

三項の例:

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

regexメソッドの利点は、正規表現が柔軟であり、さまざまなパターンに一致できることです。たとえば、varが「True」、「False」、「T」、「F」、「t」、または「f」のいずれかであると思われる場合は、正規表現を変更できます。

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

2
注:\A/ \z 文字列の開始/終了で、^/ $ラインの開始/終了です。もしそうならvar == "true\nwhatevs"、その後boolean == true
cremno 2016年

これは本当に私を助け、私はvar.eql?('true') ? true : falseとても好きです。ありがとう!
クリスチャン

3

私はハッシュアプ​​ローチが好きですが(以前は同様のものに使用しました)、真実の値の一致にのみ関心があるので、他のすべてがfalseであるため、配列に含まれているかどうかを確認できます。

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

または、他の値が真実であると見なされる可能性がある場合:

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

オリジナルvalueが大文字と小文字が混在する可能性がある場合は、他のことを行う必要があります。

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

ただし、繰り返しになりますが、問題の具体的な説明については、その最後の例を解決策として使用することができます。


2

レールでは、私は以前に次のようなことをしました:

class ApplicationController < ActionController::Base
  # ...

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

  # ...
end

これは、データベースのRailsと同じ方法でブール文字列の比較を一致させる場合に便利です。


0

すでに投稿されているものに近いが、冗長なパラメータなし:

class String
    def true?
        self.to_s.downcase == "true"
    end
end

使用法:

do_stuff = "true"

if do_stuff.true?
    #do stuff
end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.