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

问题描述 投票:0回答:18

我的值将是以下四种之一:布尔 true、布尔 false、字符串“true”或字符串“false”。 如果字符串是字符串,我想将其转换为布尔值,否则保持不变。 换句话说:

“真”应该变成真

“假”应该变成假

真实应该保持真实

假应该保持假

ruby string boolean type-conversion
18个回答
212
投票

如果你使用 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 值 - 除非该值为零或与 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


175
投票
def true?(obj)
  obj.to_s.downcase == "true"
end

43
投票

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

41
投票

在 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

35
投票

别想太多:

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”。


18
投票
if value.to_s == 'true'
  true
elsif value.to_s == 'false'
  false
end

14
投票
h = { "true"=>true, true=>true, "false"=>false, false=>false }

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

12
投票

在 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

r规格

# 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

8
投票

在 Rails 中,我更喜欢使用

ActiveModel::Type::Boolean.new.cast(value)
,如其他答案中所述

但是当我编写普通的 Ruby lib 时。然后我使用一个 hack,其中

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
投票

我对此有一个小窍门。

JSON.parse('false')
将返回
false
并且
JSON.parse('true')
将返回 true。但这不适用于
JSON.parse(true || false)
。所以,如果你使用像
JSON.parse(your_value.to_s)
这样的东西,它应该以一种简单但黑客的方式实现你的目标。


4
投票

可以使用像 https://rubygems.org/gems/to_bool 这样的 gem,但它可以使用正则表达式或三元轻松地写在一行中。

正则表达式示例:

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

4
投票

虽然我喜欢哈希方法(我过去曾将它用于类似的东西),但考虑到您只真正关心匹配真实值 - 因为 - 其他一切都是假的 - 您可以检查数组中是否包含:

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

或者其他值是否可以被视为真实:

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

如果你原来的

value
可能是混合大小写,你就必须做其他事情:

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

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


3
投票

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


3
投票

Rubocop 建议格式:

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

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


1
投票

此功能适用于任何输入:

def true?(value)
 ![false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"].include? value
end

那么你就有:

true?(param) #returns true or false 

0
投票

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

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

用途:

do_stuff = "true"

if do_stuff.true?
    #do stuff
end

0
投票

如果您希望环境变量提供数字或空值:

ENV['A'].to_i.positive?
# (unset) -> false
# A= -> false
# A=0 -> false
# A=1 -> true

-5
投票

您可以在变量前添加

!!

!!test_string
© www.soinside.com 2019 - 2024. All rights reserved.