17

在 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中有这样的设备吗?如果可能的话,我只想要一些语法糖来使代码更干净。

4

3 回答 3

31

试试Array#all?。Ifarr是一个布尔数组,它本身就可以工作:

arr.all?

true如果其中的每个元素都arr为真,则将返回,false否则。

您可以使用Array#any?相同的方式在 上加入数组||,也就是说,true如果数组中的任何元素为真则返回,否则返回false

只要您确保将正确的变量传递到块中(或使用类、实例或全局变量),这也适用arr于 的数组。ProcsProc#call

于 2013-01-14T22:55:01.667 回答
19

您可以使用#all?,#any?#none?实现此目的:

[true, false].any?
=> true

[true, false].all?
=> false

并且不要忘记,除nul和之外的所有值都false评估为true

['', [], {}].all?
=> true
于 2013-01-14T22:55:22.073 回答
2

在这种特殊情况下,您只想通过用户选择的表达式过滤表达式哈希,然后测试所有这些表达式是否为真:

cumulative_value = expression.select {|k, v| user[:input][k] }.values.all?

这将首先从表达式中选择所有有匹配user[:input]键的成员,然后它将Array#all?用于测试所选表达式中的所有值是否为真。那么你cumulative_value的要么是真的,要么是假的。

由于您的表达式值可能是 procs,因此您必须评估过滤后的表达式列表中的所有 procs,并从中构建一个 results 数组,您可以调用all?它:

cumulative_value = expression.select {|k, v| user[:input][k] }.
  values.map {|value| value.is_a?(Proc) ? value.call : value }.all?

几乎没有“语法糖”,但它可以完成工作而不会非常复杂。

于 2013-01-14T23:09:07.853 回答