Reputation: 964
I am trying to implement an "or" filtering a list in scala.
list.filter(_ % 3 ==0 || _ % 5 ==0)
but I am getting this error:
error: wrong number of parameters; expected = 1
So how can this be grouped as one parameter.
Upvotes: 2
Views: 759
Reputation: 9225
Functional alternative:
val or = (xs: List[Int => Boolean]) => (x: Int) => xs.exists(_(x))
List(0, 1, 2, 3, 4, 5, 6).filter(or(List(_ % 3 == 0, _ % 5 == 0)))
or even simpler:
val or = { def or(xs: (Int => Boolean)*) = (x: Int) => xs.exists(_(x)); or _}
List(0, 1, 2, 3, 4, 5, 6).filter(or(_ % 3 == 0, _ % 5 == 0))
UPDATE: Second version doesn't seem to work with Scala 2.10, so it's better to use method:
def or[T](xs: (T => Boolean)*) = (x: T) => xs.exists(_(x))
Upvotes: 0
Reputation: 35970
The simplest solution is to use:
list.filter(x => (x % 3 == 0) || (x % 5 == 0))
If you want to get fancy and implement an "or", take a look at how I did it with some pimping: Predicates. The simple solution afforded pimps is:
trait Pred1[A] extends (A => Boolean){
self =>
def or[AA >: A](that: AA => Boolean) = new Pred1[A]{
def apply(arg: A) = self(arg) || that(arg)
}
}
//and somewhere in the code
implicit def f2p[A](f: A => Boolean) = new Pred1[A]{ def apply(arg: A) = f(arg) }
and so on with "and", "xor", "nxor", "nor", and "nand". Then what you do is simply come up with two functions you pass into the filter.
Note, I may be possibly replacing pimping with a type class and am playing around with some ideas in another branch but have had little free time to really dig into it.
Upvotes: 0
Reputation: 62835
Don't try to be more concise than you have to:
list.filter(x => x % 3 ==0 || x % 5 ==0)
Underscores doesn't work because n-th _ is expanded to n-th argument like this:
list.filter((x,y) => x % 3 ==0 || y % 5 ==0)
Upvotes: 10
Reputation: 32335
You can only use the placeholder syntax if the parameter appears only once in the function expression. Otherwise, you have to declare the function parameter explicitly:
list.filter(x => x % 3 == 0 || x % 5 == 0)
Multiple placeholders expand to multiple method parameters.
Upvotes: 2