我有一些过滤器表示为功能列表(MyClass =>布尔)。我试图获得所有成员的逻辑连接(AND)。我有一种感觉,我可以在这里使用折叠。但我没有得到语法,尤其是如何将MyClass参数传递给函数。
答案 0 :(得分:3)
您可以在此处使用foldLeft
,但forall
更好:
def check[A](filters: Seq[A => Boolean])(a: A) = filters.forall(_(a))
其工作原理如下:
scala> val filters = Seq[Int => Boolean]((_ > 0), (_ % 2 == 1), (_ < 1000))
filters: Seq[Int => Boolean] = List(<function1>, <function1>, <function1>)
scala> check(filters)(10)
res0: Boolean = false
scala> check(filters)(103)
res1: Boolean = true
它具有懒惰的额外优势:
scala> check(filters :+ { i: Int => print(i); true })(10)
res2: Boolean = false
最后一个过滤器(有副作用)未应用,因为第二个失败。
答案 1 :(得分:2)
这很简单。假设您的List(MyClass => Boolean)
个函数名为predicates and
MyClass you are testing is named
myClass`:
val result: Boolean = predicates.foldLeft(true) {
(value, predicate) =>
value && predicate(myClass)
}
或者在包装功能中:
def conjunction(myClass: MyClass, predicates: List[MyClass => Boolean]) =
predicates.foldLeft(true) {
(value, predicate) =>
value && predicate(myClass)
}
说明:如果您的谓词列表包含三个函数:foo(myClass: MyClass): Boolean
,bar(myClass: MyClass): Boolean
和buzz(myClass: MyClass): Boolean
,则上述代码大致相当于:
((true && foo(myClass)) && bar(myClass) && buzz(myClass)
我刚才写了一篇关于such use cases of foldLeft
的文章。
答案 2 :(得分:1)
好吧,让我们考虑两个这样的谓词:
val pa: T => Boolean = ???
val pb: T => Boolean = ???
他们的结合将是这样的:
val pab: T => Boolean = (v: T) => pa(V) && pb(v)
从那里你有折叠的公式:
list.tail.foldLeft(list.head) {
case (pa, pb) => v => pa(v) && pb(v)
}
答案 3 :(得分:0)
predicates.foldLeft( true ) ( _ && _( myClass ) )
也可能有用。
答案 4 :(得分:0)
我在这些情况下所做的是使用“Pimp-My-Library”模式在谓词上添加布尔运算,这只是对结果提升到谓词上明显的布尔组合符的布尔运算。因此,我可以说像
import MyRichPredicate;
val f:Int=>Boolean = (x:Int)=>x%3==0
val g:Int=>Boolean = (x:Int)=>x%5==0
val h = f && !g //equivalent to (x:Int)=> x%3 == 0 && x%5!=0
print(h(9)) // prints true
print(h(15)) // prints false
鉴于这种管道,你想要的折叠可以写成
predicates.foldLeft(x=>true)(_&&_)
甚至更性感
predicates.reduce(_&&_)