我正在尝试编写ruby keep_if和delete_if数组方法的克隆.这是我的代码.
module Strain
def keep
self.inject([]) do |extracts, element|
yield(element) ? extracts << element : extracts
end
end
def discard
self.inject([]) do |extracts, element|
!yield(element) ? extracts << element : extracts
end
end
end
class Array
include Strain
end
Run Code Online (Sandbox Code Playgroud)
这有效.但我想做的事情如下:
def discard
self - self.keep &block
end
Run Code Online (Sandbox Code Playgroud)
期望的行为:
[1, 2, 3].discard { |number| number < 2 }
# => [2, 3]
Run Code Online (Sandbox Code Playgroud)
所以我需要传递传递给discard方法的块,然后传递给keep方法.我该如何实现这一目标?
Sim*_*tti 29
您可以显式引用该块
def discard(&block)
self - self.keep(&block)
end
Run Code Online (Sandbox Code Playgroud)
或含蓄地
def discard
self - self.keep(&Proc.new {})
end
Run Code Online (Sandbox Code Playgroud)
在你的情况下,我会建议第一种方法.
在第二个示例中,&Proc.new {}不传递块,而是创建一个新的空块。每个人都应该忽略{}它写成self.keep(&Proc.new),或只是keep(&proc)作为self.是多余的,proc是推荐的代名词Proc.new:
# passes on the block or the absence of a block
def discard(&block)
self - keep(&block)
end
# passes on the block and fails if no block given
def discard
self - keep(&proc)
end
Run Code Online (Sandbox Code Playgroud)
二者Proc.new并proc没有块使用当前方法的块。
&proc如果discard没有得到一个块就会失败。因此,如果您想传递块或不存在块(&nil根本不传递块),则第一个示例是最好的。如果丢失的块是错误的,则第二个示例(因为我对其进行了更改)是最好的。
在这两种情况下,每次调用 'discard' 时,都会创建一个新的 'Proc' 对象,并且它不是免费的。