2017-08-17 74 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 

这里不能使用“不”这个词,它是一个关键字。