2013-01-14 31 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? 

幾乎「語法糖「,但它可以完成工作而不會非常複雜。