Ruby:如何将字符串转换为布尔值

时间:2016-03-25 22:11:33

标签: ruby string boolean type-conversion

我有一个值将是以下四种情况之一:布尔值true,布尔值false,字符串" true"或字符串" false"。我想将字符串转换为布尔值,如果它是一个字符串,否则保持不变。换句话说:

"真"应该成为现实

"假"应该变得虚假

真的应该保持真实

false应该保持错误

16 个答案:

答案 0 :(得分:100)

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

答案 1 :(得分:74)

如果您使用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中,仅检查错误值 - 除非值为nil或匹配false值,否则假定为true。两个版本中的假值相同: 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

答案 2 :(得分:16)

我经常使用这种模式来扩展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

答案 3 :(得分:15)

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

答案 4 :(得分:13)

h = { "true"=>true, true=>true, "false"=>false, false=>false }

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

答案 5 :(得分:13)

不要想太多:

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,"如果你担心大写字母。

答案 6 :(得分:9)

在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

答案 7 :(得分:3)

虽然我喜欢散列方法(我过去曾经使用过类似的东西),但鉴于你只关心匹配的真值 - 因为 - 其他一切都是假的 - 你可以检查是否包含在阵列:

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

或者如果其他值可以被认为是真实的:

value = [1, true, '1', 'true'].include?(value)
如果您的原始value可能是大肆混合,您必须做其他事情:

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

但同样,对于您对问题的具体描述,您可以将最后一个示例作为您的解决方案。

答案 8 :(得分:2)

可以使用像https://rubygems.org/gems/to_bool这样的宝石,但可以使用正则表达式或三元数轻松地将其写入一行。

正则表达式示例:

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

三元例子:

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

正则表达式方法的优点是正则表达式非常灵活,可以匹配各种模式。例如,如果您怀疑var可能是“True”,“False”,“T”,“F”,“t”或“f”中的任何一个,那么您可以修改正则表达式:

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

答案 9 :(得分:2)

在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

答案 10 :(得分:2)

我对此有一点技巧。 JSON.parse('false')将返回false,而JSON.parse('true')将返回true。但这不适用于JSON.parse(true || false)。因此,如果您使用JSON.parse(your_value.to_s)之类的东西,它应该以一种简单而又骇人的方式实现您的目标。

答案 11 :(得分:1)

在rails中,我之前做过类似的事情:

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对数据库相同的方式匹配布尔字符串比较,那么这很好。

答案 12 :(得分:1)

Rubocop 建议的格式:

YOUR_VALUE.to_s.casecmp('true').zero?

https://www.rubydoc.info/gems/rubocop/0.42.0/RuboCop/Cop/Performance/Casecmp

答案 13 :(得分:0)

在Rails中,我更喜欢使用... BASE_DIR = "C:\\Users\\1Sun\\Cebula4" STATIC_URL = '/static/' STATICFILES_DIRS=[ os.path.join(BASE_DIR,'static'), ] STATIC_ROOT=os.path.join(BASE_DIR,'staticfiles') ... WEBPACK_LOADER = { 'DEFAULT' : { 'BUNDLE_DIR_NAME': 'bundles/', 'STATS_FILE': os.path.join(BASE_DIR, 'front/webpack-stats.json'), } } ... ,如此处其他答案所述

但是当我写普通的Ruby lib时。然后我会使用一种方法,其中ActiveModel::Type::Boolean.new.cast(value)(标准Ruby库)会将字符串“ true”转换为JSON.parse,将“ false”转换为true。例如:

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
  

在Ruby 2.5.1中得到确认

答案 14 :(得分:0)

接近已发布的内容,但没有冗余参数:

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

用法:

do_stuff = "true"

if do_stuff.true?
    #do stuff
end

答案 15 :(得分:-7)

那样的事情:

boolean_str = 'false'
boolean = eval(boolean_str)