У меня есть значение, которое будет одним из четырех: логическое истина, логическое ложь, строка «истина» или строка «ложь». Я хочу преобразовать строку в логическое значение, если это строка, в противном случае оставьте ее неизменной. Другими словами:
"правда" должно стать правдой
"ложь" должна стать ложной
правда должна оставаться верной
ложь должна оставаться ложной
ruby
string
boolean
type-conversion
Эмери
источник
источник
true
илиfalse
или достаточно , если результат truthy или falsey? Если последнее, thenfalse
уже является ложным, и обаtrue
и'true'
являются правдивыми, поэтому единственное значение, для которого результат еще не верен, это'false'
:if input == 'false' then true else input end
should do it.!!(if input == 'false' then true else input end)
. Второй!
преобразует возвращаемое значение в логическое значение, противоположное тому, что вы хотите; первый!
затем вносит исправления. Этот «трюк» существует уже давно. Не всем это нравится.Ответы:
источник
obj.to_s.downcase == 'true'
downcase!
и вы выделите на 1 объект меньше.downcase
будет дублировать существующую строку. Когда Frozen String Literals станет параметром Ruby по умолчанию, это будет иметь меньшее значение.Если вы используете Rails 5, вы можете это сделать
ActiveModel::Type::Boolean.new.cast(value)
.В Rails 4.2 используйте
ActiveRecord::Type::Boolean.new.type_cast_from_user(value)
.Поведение немного отличается, так как в Rails 4.2 проверяются истинное значение и ложное значение. В Rails 5 проверяются только ложные значения - если значения не равны нулю или не совпадают с ложным значением, оно считается истинным. Ложные значения одинаковы в обеих версиях:
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
источник
FALSE_VALUES
Rails также входило «нет».ActiveRecord::Type::Boolean::FALSE_VALUES << "no"
в инициализатор.ActiveModel::Type::Boolean.new.cast(value)
это чувствительно к регистру ... поэтому 'False' будет оцениваться как true, как и любая другая строка, кроме 'false'. пустые строки по''
умолчанию равны nil, а не false. ^^ Ценная информация, предоставленная здесь @thomasfedb по настройке инициализатораActiveModel::Type::Boolean.new.cast(nil)
также возвращаетсяnil
.ActiveRecord::Type::Boolean::FALSE_VALUES
он заморожен.Я часто использовал этот шаблон, чтобы расширить базовое поведение Ruby, чтобы упростить преобразование произвольных типов данных в логические значения, что упрощает работу с различными параметрами URL и т. Д.
Допустим, у вас есть параметр,
foo
который может быть:Вместо того, чтобы использовать кучу условных операторов, вы можете просто позвонить,
foo.to_boolean
и все остальное волшебство сделает за вас.В Rails я добавляю это в инициализатор, названный
core_ext.rb
почти во всех моих проектах, поскольку этот шаблон очень распространен.источник
"buy"=~/b/ => 0
Но("buy"=~/b/).to_boolean => false
Не думай слишком много:
Так,
Вы также можете добавить «.downcase», если вас беспокоят заглавные буквы.
источник
nil.to_s == 'true' #false
источник
value.to_s == 'true' ? true : false
if true then true, if false then false
Угадайте, что? Вы можете полностью удалить это!value.to_s == 'true' ? true : false
просто должно бытьvalue.to_s == 'true'
источник
В приложении rails 5.1 я использую это расширение ядра, созданное поверх
ActiveRecord::Type::Boolean
. У меня он отлично работает, когда я десериализую логическое значение из строки JSON.https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html
инициализировать основные расширения
rspec
источник
Работа в Rails 5
источник
ActiveModel::Type::Boolean.new.cast("False") # => true
... Использование to_s.downcase в вашем вводе - хорошая идеяВ Rails я предпочитаю использовать
ActiveModel::Type::Boolean.new.cast(value)
как упоминалось в других ответах здесьНо когда я пишу простой Ruby lib. затем я использую хак, где
JSON.parse
(стандартная библиотека Ruby) преобразует строку "true" вtrue
и "false" вfalse
. Например:Пример из живого приложения:
источник
У меня есть небольшая хитрость для этого.
JSON.parse('false')
вернетсяfalse
иJSON.parse('true')
вернет истину. Но это не работаетJSON.parse(true || false)
. Итак, если вы используете что-то подобное, выJSON.parse(your_value.to_s)
должны достичь своей цели простым, но хитрым способом.источник
Жемчужина вроде https://rubygems.org/gems/to_bool , но его можно легко записать в одну строку с использованием регулярного выражения или тройного выражения.
пример регулярного выражения:
троичный пример:
Преимущество метода регулярных выражений заключается в том, что регулярные выражения гибкие и могут соответствовать большому количеству шаблонов. Например, если вы подозреваете, что var может быть любым из «True», «False», 'T', 'F', 't' или 'f', вы можете изменить регулярное выражение:
источник
\A
/\z
- начало / конец строки, а^
/$
- начало / конец строки. Так что еслиvar == "true\nwhatevs"
тогдаboolean == true
.var.eql?('true') ? true : false
очень нравится . Спасибо!Хотя мне нравится хеш-подход (я использовал его в прошлом для подобных вещей), учитывая, что вы действительно заботитесь только о сопоставлении истинных значений - поскольку - все остальное ложно - вы можете проверить включение в массив:
или если другие значения могут считаться правдивыми:
вам придется делать другие вещи, если ваш оригинал
value
может быть смешанным:но опять же, для вашего конкретного описания вашей проблемы, вы могли бы уйти с этим последним примером в качестве решения.
источник
В рельсах я раньше делал что-то вроде этого:
Что хорошо, если вы пытаетесь сопоставить свои логические сравнения строк так же, как rails для вашей базы данных.
источник
Близко к тому, что уже опубликовано, но без избыточного параметра:
использование:
источник