Оцените множество булевых выражений, таких как Array # join in Ruby
В Ruby вы можете использовать Array # join для простого объединения нескольких строк с необязательным разделителем.
[ "a", "b", "c" ].join #=> "abc"
[ "a", "b", "c" ].join("-") #=> "a-b-c"
Мне интересно, есть ли хороший синтаксический сахар, чтобы сделать что-то подобное с кучей булевых выражений. Например, мне нужно &&
собрать вместе выражения. Однако, какие выражения будут использоваться, определяется пользователем. Поэтому вместо того, чтобы делать кучу
cumulative_value &&= expression[:a] if user[:input][:a]
Я хочу собрать все выражения сначала на основе ввода, а затем &&
все вместе одним махом. Что-то вроде:
be1 = x > y
be2 = Proc.new {|string, regex| string =~ regex}
be3 = z < 5 && my_object.is_valid?
[be1,be2.call("abc",/*bc/),be3].eval_join(&&)
Есть ли такое устройство в Ruby по умолчанию? Я просто хочу, чтобы какой-то синтаксический сахар сделал код чище, если это возможно.
Ответы
Ответ 1
Попробуйте Array#all?
. Если arr
является массивом булевых, это работает само по себе:
arr.all?
вернет true
, если каждый элемент в arr
равен true или false
в противном случае.
Вы можете использовать Array#any?
таким же образом для присоединения массива на ||
, то есть он возвращает true
, если любой элемент массива имеет значение true и false
в противном случае.
Это также будет работать, если arr
является массивом Procs
, если вы обязательно передадите правильные переменные в Proc#call
в блоке (или используйте класс, экземпляр или глобальные переменные).
Ответ 2
Вы можете использовать #all?
, #any?
и #none?
для достижения этой цели:
[true, false].any?
=> true
[true, false].all?
=> false
И не забывайте, что все значения, отличные от nul
и false
, оцениваются до true
.
['', [], {}].all?
=> true
Ответ 3
В этом конкретном случае вы просто хотите отфильтровать хэш хэша теми, которые выбрали пользователь, а затем проверить, являются ли все эти выражения правными:
cumulative_value = expression.select {|k, v| user[:input][k] }.values.all?
Сначала будут выбраны все элементы из выражения, для которых существует соответствующий user[:input]
ключ, затем он будет использовать Array#all?
, чтобы проверить, действительно ли все значения из выбранных выражений являются правдивыми. Твой cumulative_value
будет либо истинным, либо ложным.
Так как ваши значения выражения могут быть procs, вам нужно будет оценить все proc из списка фильтрованных выражений и построить массив результатов из этого, который вы можете назвать all?
on:
cumulative_value = expression.select {|k, v| user[:input][k] }.
values.map {|value| value.is_a?(Proc) ? value.call : value }.all?
Вряд ли "синтаксический сахар", но он выполняет свою работу, не будучи ужасно сложным.