2

我正在尝试在scala中实现“或”过滤列表。

    list.filter(_ % 3 ==0 || _ % 5 ==0)

但我收到此错误:

error:参数个数错误;预期 = 1

那么如何将其归为一个参数。

4

4 回答 4

10

不要试图比你必须的更简洁:

list.filter(x => x % 3 ==0 || x % 5 ==0)

下划线不起作用,因为第 n 个 _ 扩展为第 n 个参数,如下所示:

list.filter((x,y) => x % 3 ==0 || y % 5 ==0)
于 2013-07-16T13:55:34.427 回答
2

如果参数仅在函数表达式中出现一次,则只能使用占位符语法。否则,您必须显式声明函数参数:

list.filter(x => x % 3 == 0 || x % 5 == 0)

多个占位符扩展到多个方法参数。

于 2013-07-16T13:55:25.597 回答
0

最简单的解决方案是使用:

list.filter(x => (x % 3 == 0) || (x % 5 == 0))

如果你想花哨并实现一个“或”,看看我是如何用一些拉皮条做到的:Predicates。为皮条客提供的简单解决方案是:

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”、“xor”、“nxor”、“nor”和“nand”。然后你所做的只是想出两个传递给过滤器的函数。

请注意,我可能正在用类型类替换拉皮条,并且正在另一个分支中玩弄一些想法,但几乎没有空闲时间来真正深入研究它。

于 2013-07-16T14:01:26.647 回答
0

功能替代品:

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)))

甚至更简单:

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))

更新:第二个版本似乎不适用于 Scala 2.10,所以最好使用方法:

def or[T](xs: (T => Boolean)*) = (x: T) => xs.exists(_(x))
于 2013-07-16T17:12:27.140 回答