高阶函数切换谓词方法

时间:2017-08-17 11:41:28

标签: ruby

有没有办法将谓词方法与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?))

3 个答案:

答案 0 :(得分:4)

在您的情况下,可以使用Enumerable#reject方法:

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

如果您需要将自定义谓词与any?all?方法结合使用,则可以根据De Morgan's laws`来实现:

any?(&:predicate?) == !all? { |obj| !obj.predicate? }

例如:

require 'prime'

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

答案 1 :(得分:2)

不,有两种方式:

  • 使用reject

    (1..10).reject(&:prime?)
    
  • 展开块

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

答案 2 :(得分:2)

当然,只要实施你的否定者。不要记得stdlib中是否存在这样的东西。

require 'prime'

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

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

不能使用"而不是"在这里,它是一个关键字。