4

In ruby, the following expression: x.filter {|n| n.even?} can also be written as: x.filter(&:even?) so, I am wondering how I would write this expression? x.filter {|n| !n.even?} without using odd? method

  • 1
    The proc would essentially be called as to_proc on the object. Your negation is on the object, so unless you store it as a proc, you cant call it. Though if this is actual code, then why not x.filter(&:odd?) ? – Sam Aug 19 '16 at 16:48
  • 1
    `even?` is a method being called on the given object which is how `Symbol#to_proc` works where as `!`(not) is being called bypassing the return value to `BasicObject#!`. Thus you cannot write it in this fashion. You could add a method `not_even?` but that just means `odd?` so why not use `odd?`. If `x` is enumerable (includes `Enumerable`) then you could do `_, not_even = x.partition(&:even?)` but I don't think this is what you were looking for. – engineersmnky Aug 19 '16 at 17:40
  • 1
    just want to point out that you always have the `reject` counterpart to `filter`/`select`. Do see [this answer](http://stackoverflow.com/a/23711606/2981429) which shows some symbol-to-proc hackery. Might be best to avoid the tricks, though, if others will be reading the code. – max pleaner Aug 19 '16 at 18:12

1 Answers1

4

As Sam and engineerskmnky said in the comments below question, it is not possible to perform x.filter { |n| !n.even? } operation directly (and in fact two operations inside the block).

I guess that this was only a trivial example and not a real code so if you have method that does not have the inverse one and you don't want to create one, you can create a lambda or proc in the following way:

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

and then call it on filter as:

x.filter(&not_even)

You can also use reject method which should give you the same result without the magic of using lambda.

Maciej Małecki
  • 2,725
  • 19
  • 29