4

関数 List(MyClass => Boolean) のリストとして表現されるフィルターがいくつかあります。すべてのメンバーの論理積 (AND) を取得しようとしています。ここで折り畳みを使用できる気がしますが、特に MyClass 引数を関数に渡す方法に関する構文がわかりません。

4

5 に答える 5

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

2 番目のフィルターが失敗するため、最後のフィルター (副作用があります) は適用されません。

于 2012-06-12T18:26:32.510 に答える
2

それはとても簡単です。List(MyClass => Boolean)関数の名前がpredicates andMyClass you are testing is namedmyClass`であると仮定します。

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

説明: 述語のリストが次の 3 つの関数で構成されている場合foo(myClass: MyClass): Boolean、上記のコードは次bar(myClass: MyClass): Booleanbuzz(myClass: MyClass): Booleanほぼ同等です。

((true && foo(myClass)) && bar(myClass) && buzz(myClass)

このような の使用例foldLeftについて、少し前に記事を書きました。

于 2012-06-12T18:18:51.450 に答える
1

では、そのような述語を 2 つ考えてみましょう。

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)
}
于 2012-06-12T18:36:36.190 に答える
0

predicates.foldLeft( true ) ( _ && _( myClass ) )また動作する可能性があります。

于 2012-06-12T18:24:57.363 に答える
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(_&&_)
于 2012-06-12T20:07:05.623 に答える