रूबी: एक स्ट्रिंग को बूलियन में कैसे परिवर्तित करें


107

मेरे पास एक मूल्य है जो चार चीजों में से एक होगा: बूलियन सच, बूलियन झूठी, स्ट्रिंग "सच", या स्ट्रिंग "झूठी"। मैं स्ट्रिंग को बूलियन में बदलना चाहता हूं यदि यह एक स्ट्रिंग है, अन्यथा इसे अनमॉडिफाइड छोड़ दें। दूसरे शब्दों में:

“सच्चा” सच्चा बनना चाहिए

"असत्य" असत्य हो जाना चाहिए

सच को सच रहना चाहिए

असत्य को झूठ ही रहना चाहिए


2
परिणाम यह है है दो मानों में से एक है trueया falseया यह पर्याप्त है अगर परिणाम truthy या falsey है? उत्तरार्द्ध है, तो falseपहले से ही falsey है, और दोनों trueऔर 'true', truthy हैं, इसलिए केवल मान जिसके परिणाम पहले से ही सही नहीं है, है 'false': if input == 'false' then true else input endयह क्या करना चाहिए।
जोर्ग डब्ल्यू मित्ग

यह एक शानदार टिप्पणी है जोर्ग, हालांकि मैं यह मानूंगा कि कुछ अनुप्रयोगों के लिए बूलियन मान सही या गलत होना आवश्यक है, न कि केवल एक मूल्य जो सत्य या असत्य है।
एमरी

2
एमरी, यदि आपको एक बूलियन वापस करने की आवश्यकता है तो आप दो "नोट" के साथ @ जोर्ज की अभिव्यक्ति को रोक सकते हैं !!(if input == 'false' then true else input end):। दूसरा !वापसी मूल्य को एक बूलियन में परिवर्तित करता है जो आप चाहते हैं के विपरीत है; पहले !तो सुधार करता है। यह "चाल" लंबे समय से है। हर कोई इसका शौकीन नहीं होता।
कैरी स्वेवेलैंड

जवाबों:


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

3
हां, @null, to_s विधि बूलियन को सही या गलत को "सही" या "गलत" में परिवर्तित करती है और मूल रूप से एक स्ट्रिंग होने पर मान को अपरिवर्तित छोड़ देती है। अब हम एक स्ट्रिंग के रूप में या तो "सही" या "झूठे" होना निश्चित हैं ... और हमें केवल उपयोग करने की आवश्यकता है == जांचें कि क्या स्ट्रिंग "सच" के बराबर है। यदि यह है तो मूल मूल्य या तो सच था या "सच" था। यदि यह नहीं है, तो मूल मूल्य गलत था, "झूठा", या कुछ पूरी तरह से असंबंधित।
एमरी

8
चूँकि स्ट्रिंग को ऊपर किया जा सकता है / शीर्षक दिया जा सकता है, इसलिए नीचे उतारने से एक मैच सुनिश्चित होगा:obj.to_s.downcase == 'true'
TDH

1
उपयोग करें downcase!और आप 1 कम ऑब्जेक्ट आवंटित करेंगे। downcaseमौजूदा स्ट्रिंग को डुप्लिकेट करेगा। जब फ्रोजन स्ट्रिंग लिटरल्स रूबी डिफ़ॉल्ट विकल्प बन जाता है, तो यह कम मायने रखता है।
danielricecodes

मैंने नीचे के सुझाव को शामिल करने के लिए उत्तर को संपादित करने की स्वतंत्रता ली! उपरोक्त टिप्पणियों के अनुसार। यह पढ़ने में कम सुरुचिपूर्ण है, लेकिन यदि आप सुनिश्चित नहीं हैं कि आप किस प्रकार के चर के साथ काम कर रहे हैं, तो अधिक मजबूती कभी खराब नहीं होती है।
एमरी

यदि आप इसे खराब डेटा खिलाते हैं, तो यह एक त्रुटि की रिपोर्ट नहीं करता है, इसलिए यदि आपको किसी भी त्रुटि से निपटने की आवश्यकता है तो यह एक महान समाधान नहीं है
टॉबी 1 केनोबी

118

यदि आप रेल 5 का उपयोग करते हैं, तो आप कर सकते हैं ActiveModel::Type::Boolean.new.cast(value)

रेल्स 4.2 में, उपयोग करें ActiveRecord::Type::Boolean.new.type_cast_from_user(value)

व्यवहार थोड़ा अलग है, जैसा कि रेल 4.2 में, सही मूल्य और झूठे मूल्यों की जांच की जाती है। रेल 5 में, केवल झूठे मूल्यों की जाँच की जाती है - जब तक कि मान शून्य नहीं है या गलत मूल्य से मेल नहीं खाता है, तब तक इसे सही माना जाता है। दोनों संस्करणों में गलत मान समान हैं: FALSE_VALUES = [false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"]

रेल्स 5 स्रोत: https://github.com/rails/rails/blob/5-1-stable/activemodel/lib/active_model/type/boolean.rb


1
यह सहायक है, हालांकि मैं चाहता हूं कि FALSE_VALUESरेल के सेट में "नहीं" भी शामिल है।
pjrebsch

3
@pjrebsch अपने ऐप में पैच करने के लिए काफी सरल है। बस ActiveRecord::Type::Boolean::FALSE_VALUES << "no"एक इनिशियलाइज़र में जोड़ें ।
thomasfedb

ध्यान दें कि ActiveModel::Type::Boolean.new.cast(value)मामला संवेदनशील है ... इसलिए 'असत्य' को छोड़कर किसी भी अन्य स्ट्रिंग के रूप में 'गलत' सही का मूल्यांकन करेगा। खाली तार ''डिफ़ॉल्ट रूप से शून्य होते हैं, झूठे नहीं। ^ ^ इनिशियलाइज़ कस्टमाइज़ेशन पर @thomasfedb द्वारा यहां दी गई बहुमूल्य अंतर्दृष्टि
ठंढिनी

1
ActiveModel::Type::Boolean.new.cast(nil)भी लौटता है nil
निकोले डी

1
रेल 5.2.4 के रूप में @thomasfedb द्वारा सुझाई गई विधि अब काम नहीं करती क्योंकि ActiveRecord::Type::Boolean::FALSE_VALUESजमे हुए हैं।
मूव्स

24

मैंने अक्सर रूबी के मुख्य व्यवहार का विस्तार करने के लिए इस पैटर्न का उपयोग किया है ताकि बूलियन मानों के लिए मनमाने ढंग से डेटा प्रकारों से निपटने में आसानी हो, जिससे 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 गलत है, अन्य सभी सत्य हैं)
  • एक सच्चा बूलियन (सच्चा / झूठा)
  • एक स्ट्रिंग ("सच", "गलत", "0", "1", "सही", "FALSE")
  • शून्य

सशर्त समूहों का उपयोग करने के बजाय, आप बस कॉल कर सकते हैं foo.to_booleanऔर यह आपके लिए बाकी का जादू करेगा।

रेल में, मैं इसे 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

यह बहुत अच्छी तरह से काम करता है, जैसे। क्या "खरीदना" एक "बी" से शुरू होता है? "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

अगर आप बड़े अक्षरों के बारे में चिंतित हैं, तो आप ".adcase" को भी जोड़ सकते हैं।


5
nil.to_s == 'true' #false
जूलियागोनजेल

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

10
वन-लाइनर के रूप में आपका कोडvalue.to_s == 'true' ? true : false
सागर पंड्या

20
@ sagarpandya82: ऐसा कभी न करें, यह सशर्त ऑपरेटर के उद्देश्य को पराजित करता है: if true then true, if false then falseलगता है क्या? आप इसे पूरी तरह से हटा सकते हैं! value.to_s == 'true' ? true : falseबस होना चाहिएvalue.to_s == 'true'
एरिक डुमिनील 22

4
@EricDuminil उस समय बिल्कुल सहमत, धोखेबाज़ त्रुटि।
सागर पंड्या

2
ध्यान दें कि यह उत्तर शून्य वापस आ जाएगा जब मूल्य को परिवर्तित नहीं किया जा सकता है, जबकि वे वन-लाइनर्स कभी भी विफल नहीं होंगे और हमेशा झूठे वापस आएंगे जब तक कि मूल्य 'सही' न हो। दोनों वैध दृष्टिकोण हैं और विभिन्न स्थितियों के लिए सही उत्तर हो सकते हैं, लेकिन वे समान नहीं हैं।
दाउद

1
@AndreFigueiredo टर्नेरी ऑपरेटर इस मामले में कुछ नहीं करता है। बिना कोशिश करें, और परिणामों की तुलना करें।
एरिक डुमिनील


7

एक रेल 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

यह पूर्ण है। ठीक वही जो मेरे द्वारा खोजा जा रहा था।
डग

5

रेल में मैं ActiveModel::Type::Boolean.new.cast(value)अन्य उत्तरों के रूप में यहां उपयोग करना पसंद करता हूं

लेकिन जब मैं सादे रूबी लिबास लिखता हूं। तब मैं एक हैक का उपयोग करता हूं जहां JSON.parse(मानक रूबी पुस्तकालय) स्ट्रिंग को "सही" 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

लाइव एप्लिकेशन से उदाहरण:

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

रूबी 2.5.1 के तहत पुष्टि की गई


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')लौटेगा falseऔर JSON.parse('true')सच लौटेगा। लेकिन यह साथ काम नहीं करता है JSON.parse(true || false)। तो, अगर आप कुछ इस तरह का उपयोग करते हैं तो JSON.parse(your_value.to_s)यह आपके लक्ष्य को एक सरल लेकिन आसान तरीके से प्राप्त करना चाहिए।


3

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' में से कोई भी हो सकता है, तो आप regex को संशोधित कर सकते हैं:

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

2
नोट: \A/ \z स्ट्रिंग का प्रारंभ / अंत है और ^/ $लाइन का प्रारंभ / अंत है। तो अगर var == "true\nwhatevs"तब boolean == true
क्रेमनो

इससे मुझे बहुत मदद मिली और मुझे var.eql?('true') ? true : falseबहुत अच्छा लगा। धन्यवाद!
क्रिश्चियन

3

हालाँकि मुझे हैश एप्रोच पसंद है (मैंने इसे इसी तरह के सामान के लिए अतीत में इस्तेमाल किया है), यह देखते हुए कि आप केवल सचाई के मूल्यों के मिलान की परवाह करते हैं - क्योंकि - बाकी सब गलत है - आप किसी ऐरे में शामिल होने की जाँच कर सकते हैं:

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

यदि आप अपने बूलियन स्ट्रिंग्स की तुलना उसी तरह से करना चाहते हैं, जो आपके डेटाबेस के लिए रेल के समान होगा।


0

जो पहले से पोस्ट किया गया है, उसके करीब है, लेकिन अनावश्यक पैरामीटर के बिना:

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

उपयोग:

do_stuff = "true"

if do_stuff.true?
    #do stuff
end
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.