2017-08-17 95 views
0

是否有方法可以將謂詞方法與Enumerable接口組合切換?高階函數切換謂詞方法

require 'prime' 

(1..10).select(&:prime?) 
# => [2, 3, 5, 7] 

# Toggling the prime? predicate? 
(1..10).select(not(&:prime?)) 
# SyntaxError: (irb):3: syntax error, unexpected &, expecting ')' 

具體而言,我需要另一個謂詞,如果所有元素都不滿足自定義謂詞,則返回true。

# concrete example 
set.all?(not(:&custom_predicate?)) 

回答

4

你的情況Enumerable#reject方法可用於:

(1..10).reject(&:prime?) 

如果你需要切換組合自定義謂詞any?all?方法,它可根據De Morgan's laws`實現的:

例如:
require 'prime' 

(1..10).any?(&:prime?) == !(1..10).all? { |num| !num.prime? } 
+1

我將我的評論移到了問題上,以使我的選擇合理。 – sschmeck

2

不,有兩種方式:

  • 使用reject

    (1..10).reject(&:prime?) 
    
  • 擴大塊

    (1..10).select { |n| !n.prime? } 
    
+0

實際上,這是完全可行的,只需一些代碼。 :) –

+0

哦,是的,當然。我的意思是沒有開箱即用的解決方案 – Ursus

+1

我不會那麼肯定。 Stdlib是huuuge,有很多黑暗的角落:) –

2

當然,只是實施你的否定者。不記得stdlib中是否存在這樣的事情。

require 'prime' 

def nay(&proc) 
    ->(obj) { !proc.call(obj) } 
end 

puts (1..10).select(&nay(&:prime?)) 
# >> 1 
# >> 4 
# >> 6 
# >> 8 
# >> 9 
# >> 10 

這裏不能使用「不」這個詞,它是一個關鍵字。