2013-01-14 112 views
15

在Ruby中,可以使用Array#join将多个字符串与可选分隔符简单地连接在一起。评估许多布尔表达式,如Ruby中的Array#连接

[ "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

你希望每个部分都有参数和动态变化吗?或者他们以前是否确定?例如'be1'没有意义,除非已经给出'x'和'y',在这种情况下,它将是'true'或'false'的常量,但'be2'是一个proc,它总是评估到一个真实的价值,这也是一个常数,除非你打算将它用于某些论证,否则它就没有多大意义。看来你在混合这些。 – sawa

回答

24

尝试Array#all?。如果arr是布尔数组,这个工作本身:

arr.all? 

将返回true如果arr每一个元素是真实的,或者以其他方式false

可以以相同的方式使用Array#any?用于接合在阵列上||,也就是说,它返回true如果阵列中的任何元素是真实的,否则false

如果arrProcs的数组,则只要您确保在块中(或使用类,实例或全局变量)将正确的变量传递给Proc#call,这也可以工作。

17

您可以使用#all?#any?#none?来实现这一目标:

[true, false].any? 
=> true 

[true, false].all? 
=> false 

而且不要忘了,这比nulfalse其他所有值评估为true

['', [], {}].all? 
=> true 
+0

太棒了!真的很高兴知道它。 –

2

在这种特殊情况下,你只是想通过这些用户已选择过滤你的表情哈希,然后测试,如果所有的表达式都truthy:

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

这将首先选择所有表达式中存在匹配的user[:input]键的成员,则将使用Array#all?来测试所选表达式中的所有值是否为真。那么你的cumulative_value就是真或假。

因为你的表达值可能是特效,你将不得不评估从过滤表达式列表中的所有特效,并建立从一个结果数组,你可以调用all?

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

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