2016-08-19 56 views
3

在Ruby中,下面的表达式: x.filter {|n| n.even?} 也可以写为: x.filter(&:even?) 所以,我想知道我怎么会写这样的表达? x.filter {|n| !n.even?} 而不使用odd?方法Ruby:取消散列传递给proc?

+1

proc本质上被称为to_proc对象。你的否定是在对象上的,所以除非你把它作为一个proc来存储,否则你不能称它。虽然如果这是实际的代码,那为什么不用x.filter(&:odd?)? – Sam

+1

'even?'是一个在给定对象上调用的方法,它是'Symbol#to_proc'的工作方式,因为'!'(不)被绕过返回值到'BasicObject#!'。所以你不能用这种方式写。你可以添加一个'not_even?'方法,但这只意味着'奇怪',那么为什么不使用'odd?'。如果'x'是可枚举的(包括'Enumerable'),那么你可以做'_,not_even = x.partition(&:even?)',但我不认为这就是你想要的。 – engineersmnky

+1

只是想指出,你总是有'过滤器'''选择''拒绝'对应。看看[这个答案](http://stackoverflow.com/a/23711606/2981429),它显示了一些符号到程序的hackery。但是,如果其他人将阅读代码,可能最好避免这些技巧。 –

回答

3

如萨姆和engineerskmnky在下面讨论的评论说,这是不可能直接执行x.filter { |n| !n.even? }操作(并且事实上该块内的两个操作)。

我想这只是一个简单的例子,而不是一个真实的代码,所以如果你有没有相反的方法,你不想创建一个,你可以在下面创建一个lambda或proc方法:

not_even = -> (n) { !n.even? } 

然后调用它的过滤器:

x.filter(&not_even) 

您还可以使用reject方法,它应该给你同样的结果,而无需使用拉姆达的魔力。

+0

没错。很多像'filter'这样的Ruby方法都有它们的否定对象,例如'reject'。 – tadman

+0

谢谢。拒绝听起来像是一个很好的选择 –

相关问题