Saya memiliki nilai yang akan menjadi salah satu dari empat hal: boolean true, boolean false, string "true", atau string "false". Saya ingin mengubah string menjadi boolean jika itu adalah string, jika tidak biarkan tidak diubah. Dengan kata lain:
"benar" harus menjadi kenyataan
"false" harus menjadi salah
benar harus tetap benar
salah harus tetap salah
ruby
string
boolean
type-conversion
amril
sumber
sumber
true
ataufalse
atau itu cukup jika hasilnya adalah truthy atau falsey? Jika yang terakhir, makafalse
sudah salah, dan keduanyatrue
dan'true'
benar, jadi satu-satunya nilai yang hasilnya belum benar, adalah'false'
:if input == 'false' then true else input end
harus melakukannya.!!(if input == 'false' then true else input end)
. Yang kedua!
mengubah nilai kembali menjadi boolean yang berlawanan dengan yang Anda inginkan; yang pertama!
kemudian melakukan koreksi. "Trik" ini sudah ada sejak lama. Tidak semua orang menyukainya.Jawaban:
sumber
obj.to_s.downcase == 'true'
downcase!
dan Anda akan mengalokasikan 1 objek lebih sedikit.downcase
akan menduplikasi string yang ada. Ketika Frozen String Literals menjadi opsi default Ruby, ini tidak terlalu penting.Jika Anda menggunakan Rails 5, Anda bisa melakukannya
ActiveModel::Type::Boolean.new.cast(value)
.Di Rails 4.2, gunakan
ActiveRecord::Type::Boolean.new.type_cast_from_user(value)
.Perilakunya sedikit berbeda, seperti pada Rails 4.2, nilai benar dan nilai salah diperiksa. Di Rails 5, hanya nilai salah yang diperiksa - kecuali nilainya nihil atau cocok dengan nilai salah, ini dianggap benar. Nilai salah sama di kedua versi:
FALSE_VALUES = [false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"]
Rails 5 Sumber: https://github.com/rails/rails/blob/5-1-stable/activemodel/lib/active_model/type/boolean.rb
sumber
FALSE_VALUES
di Rails juga menyertakan "no".ActiveRecord::Type::Boolean::FALSE_VALUES << "no"
ke penginisialisasi.ActiveModel::Type::Boolean.new.cast(value)
case sensitive ... jadi 'False' akan dievaluasi menjadi true seperti halnya string lainnya kecuali 'false'. string kosong''
default ke nil, bukan false. ^^ wawasan berharga diberikan di sini oleh @thomasfedb tentang penyesuaian penginisialisasiActiveModel::Type::Boolean.new.cast(nil)
juga kembalinil
.ActiveRecord::Type::Boolean::FALSE_VALUES
dibekukan.Saya sering menggunakan pola ini untuk memperluas perilaku inti Ruby agar lebih mudah menangani konversi tipe data arbitrer ke nilai boolean, yang membuatnya sangat mudah untuk menangani berbagai parameter URL, dll.
Jadi katakanlah Anda memiliki parameter
foo
yang dapat berupa:Alih-alih menggunakan sekumpulan persyaratan, Anda bisa menelepon
foo.to_boolean
dan itu akan melakukan sisanya untuk Anda.Di Rails, saya menambahkan ini ke penginisialisasi yang dinamai
core_ext.rb
di hampir semua proyek saya karena pola ini sangat umum.sumber
"buy"=~/b/ => 0
Tapi("buy"=~/b/).to_boolean => false
Jangan terlalu banyak berpikir:
Begitu,
Anda juga dapat menambahkan ".downcase", jika Anda mengkhawatirkan huruf kapital.
sumber
nil.to_s == 'true' #false
sumber
value.to_s == 'true' ? true : false
if true then true, if false then false
Coba tebak? Anda dapat menghapusnya sepenuhnya!value.to_s == 'true' ? true : false
seharusnya hanyavalue.to_s == 'true'
sumber
Di aplikasi rel 5.1, saya menggunakan ekstensi inti yang dibangun di atasnya
ActiveRecord::Type::Boolean
. Ini bekerja dengan sempurna untuk saya ketika saya menghilangkan boolean dari string JSON.https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html
menginisialisasi ekstensi inti
rspec
sumber
Di Rails saya lebih suka menggunakan
ActiveModel::Type::Boolean.new.cast(value)
seperti yang disebutkan dalam jawaban lain di siniTetapi ketika saya menulis lib Ruby biasa. kemudian saya menggunakan hack di mana
JSON.parse
(library Ruby standar) akan mengubah string "true" menjaditrue
dan "false" menjadifalse
. Misalnya:Contoh dari aplikasi langsung:
sumber
Bekerja di Rails 5
sumber
ActiveModel::Type::Boolean.new.cast("False") # => true
... Gunakan to_s.downcase pada masukan Anda adalah ide yang bagusSaya memiliki sedikit retasan untuk yang satu ini.
JSON.parse('false')
akan kembalifalse
danJSON.parse('true')
akan kembali benar. Tapi ini tidak berhasilJSON.parse(true || false)
. Jadi, jika Anda menggunakan sesuatu sepertiJSON.parse(your_value.to_s)
itu harus mencapai tujuan Anda dengan cara yang sederhana namun hacky.sumber
Permata seperti https://rubygems.org/gems/to_bool dapat digunakan, tetapi dapat dengan mudah ditulis dalam satu baris menggunakan regex atau terner.
contoh regex:
contoh terner:
Keuntungan metode regex adalah ekspresi reguler fleksibel dan dapat mencocokkan berbagai pola. Misalnya, jika Anda mencurigai bahwa var dapat berupa salah satu dari "True", "False", 'T', 'F', 't', atau 'f', maka Anda dapat memodifikasi regex:
sumber
\A
/\z
adalah awal / akhir string dan^
/$
adalah awal / akhir baris. Jadi kalauvar == "true\nwhatevs"
begituboolean == true
.var.eql?('true') ? true : false
sangat menyukainya. Terima kasih!Meskipun saya suka pendekatan hash (saya pernah menggunakannya di masa lalu untuk hal-hal serupa), mengingat Anda hanya benar-benar peduli tentang pencocokan nilai kebenaran - karena - yang lainnya salah - Anda dapat memeriksa penyertaan dalam array:
atau jika nilai-nilai lain dapat dianggap benar:
Anda harus melakukan hal-hal lain jika aslinya
value
mungkin casing campuran:tetapi sekali lagi, untuk deskripsi spesifik Anda tentang masalah Anda, Anda dapat menggunakan contoh terakhir sebagai solusi Anda.
sumber
Di rel, saya sebelumnya telah melakukan sesuatu seperti ini:
Yang bagus jika Anda mencoba mencocokkan perbandingan string boolean dengan cara yang sama seperti rail untuk database Anda.
sumber
Dekat dengan apa yang sudah diposting, tetapi tanpa parameter yang berlebihan:
pemakaian:
sumber