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

eme*_*ery 89 ruby string boolean type-conversion

我有一个值将是四件事之一:布尔值true,布尔值false,字符串"true"或字符串"false".我想将字符串转换为布尔值,如果它是一个字符串,否则保持不变.换一种说法:

"真实"应该成真

"假"应该变成虚假

真的应该保持真实

假应该保持虚假

ste*_*lag 112

def true?(obj)
  obj.to_s.downcase == "true"
end
Run Code Online (Sandbox Code Playgroud)

  • 这太棒了,cna有人解释它是如何工作的? (11认同)
  • 由于字符串可能是upcased/titled,downcasing将确保匹配:`obj.to_s.downcase =='true' (8认同)
  • 是的,@ null,to_s方法将布尔值true或false转换为"true"或"false",如果最初是一个字符串,则保持值不变.现在我们肯定要将"true"或"false"作为字符串......我们只需要使用==检查字符串是否等于"true".如果是,则原始值为true或"true".如果不是,则原始值为false,"false"或完全不相关的值. (3认同)
  • 使用 `downcase!` 并且你会少分配 1 个对象。`downcase` 将复制现有的字符串。当 Frozen String Literals 成为 Ruby 默认选项时,这将变得无关紧要。 (3认同)

rad*_*ado 92

如果你使用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

  • 从 Rails 5.2.4 开始,@thomasfedb 建议的方法不再有效,因为 `ActiveRecord::Type::Boolean::FALSE_VALUES` 已被冻结。 (4认同)
  • @pjrebsch在你的应用程序中修补相当简单.只需将`ActiveRecord :: Type :: Boolean :: FALSE_VALUES <<"no"`添加到初始化程序中. (3认同)
  • `ActiveModel::Type::Boolean.new.cast(nil)` 也返回 `nil`。 (3认同)
  • 这很有帮助,尽管我希望 Rails 中的“FALSE_VALUES”集也包含“否”。 (2认同)
  • 请注意,“ActiveModel::Type::Boolean.new.cast(value)”区分大小写...因此“False”将评估为 true,就像除“false”之外的任何其他字符串一样。空字符串 `''` 默认为 nil,而不是 false。^^ @thomasfedb 在此提供了关于初始化程序定制的宝贵见解 (2认同)

Ste*_*aig 20

我经常使用这种模式来扩展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
Run Code Online (Sandbox Code Playgroud)

所以假设你有一个参数foo可以是:

  • 一个整数(0表示假,其他都是真)
  • 一个真的布尔值(true/false)
  • 一个字符串("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
Run Code Online (Sandbox Code Playgroud)


Dav*_*ley 17

不要想太多:

bool_or_string.to_s == "true"  
Run Code Online (Sandbox Code Playgroud)

所以,

"true".to_s == "true"   #true
"false".to_s == "true"  #false 
true.to_s == "true"     #true
false.to_s == "true"    #false
Run Code Online (Sandbox Code Playgroud)

如果您担心大写字母,也可以添加".downcase".

  • `nil.to_s =='true'#false` (5认同)

arc*_*ana 15

if value.to_s == 'true'
  true
elsif value.to_s == 'false'
  false
end
Run Code Online (Sandbox Code Playgroud)

  • @ sagarpandya82:永远不要这样做,它会破坏条件运算符的目的:`如果为true则为true,如果为false则为false`猜猜是什么?你可以完全删除它!`value.to_s =='true'?true:false`应该只是`value.to_s =='true' (18认同)
  • 您的代码是一行的`value.to_s =='true'?true:false` (9认同)
  • @EricDuminil绝对同意,菜鸟在当时的错误. (4认同)
  • 请注意,当无法转换该值时,该答案将返回nil,而那些单行将永不失败,并且除非该值为'true',否则始终返回false。两者都是有效的方法,可能是针对不同情况的正确答案,但是它们并不相同。 (2认同)

Car*_*and 13

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

["true", true, "false", false].map { |e| h[e] }
  #=> [true, true, false, false] 
Run Code Online (Sandbox Code Playgroud)


Jig*_*att 13

在 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
Run Code Online (Sandbox Code Playgroud)

  • `ActiveModel::Type::Boolean.new.cast("False") # =&gt; true` ... 在输入中使用 to_s.downcase 是一个好主意 (8认同)
  • @RicardoVillamil 为什么你需要测试“fals”或“falso”是否是布尔值? (5认同)

mni*_*chi 9

在 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
Run Code Online (Sandbox Code Playgroud)

初始化核心扩展

# config/initializers/core_extensions.rb
String.include CoreExtensions::String
Run Code Online (Sandbox Code Playgroud)

规格

# 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
Run Code Online (Sandbox Code Playgroud)


小智 5

我对此有一个小窍门。JSON.parse('false')将返回false并将JSON.parse('true')返回true。但这不适用于JSON.parse(true || false). 因此,如果您使用类似的东西,JSON.parse(your_value.to_s)应该以一种简单但黑客的方式实现您的目标。


equ*_*nt8 5

在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
Run Code Online (Sandbox Code Playgroud)

实时应用程序中的示例:

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

在Ruby 2.5.1中得到确认