マップ、フラットマップなどの関数を適用するときに、フィルタの代わりにwithFilterを使用すると、よりパフォーマンスが向上しますか?with filterフィルタの代わりに
map、flatmap、foreachのみがサポートされているのはなぜですか? (forall/likeのような期待される関数)
マップ、フラットマップなどの関数を適用するときに、フィルタの代わりにwithFilterを使用すると、よりパフォーマンスが向上しますか?with filterフィルタの代わりに
map、flatmap、foreachのみがサポートされているのはなぜですか? (forall/likeのような期待される関数)
注:違い
c filter p
とc withFilter p
の間にあるのは、前者の が新しいコレクションを作成するのに対し、後者はのドメイン続いてmap
,flatMap
,foreach
およびwithFilter
の操作を含む。
のでfilter
は、元のコレクションを取得し、新しいコレクションを作るが、withFilter
は非厳密(すなわちなまけ)意志(フィルタを介して第2のパスを保存し、に後でmap
/flatMap
/withFilter
呼び出しによってフィルタリングされていない値を渡します)コレクション。したがって、これらの後続のメソッド呼び出しを通過すると、より効率的になります。
実際には、withFilter
は、これらの方法のチェーンで作業するために特別に設計されています。これは理解のために解説されています。これには他の方法(forall
/exists
など)は必要ありません。したがって、FilterMonadic
戻り値タイプwithFilter
には追加されていません。
回避策として、map
とflatMap
だけを使って他の関数を実装することができます。
また、この最適化は収量のために使用
は、例えば、回避することができます...小さなコレクションに無用です:
for {
e <- col;
if e isNotEmpty
} yield e.get(0)
the excellent answer of Shadowlandsのほかに、filter
とwithFilter
の違いの直観的な例を紹介したいと思います。
はのは、ほとんどの人はresult
がList(1)
に等しくなるように期待して、次のコード
val list = List(1, 2, 3)
var go = true
val result = for(i <- list; if(go)) yield {
go = false
i
}
を考えてみましょう。あなたは翻訳がwithFilter
への呼び出しに条件を変換見ることができるようにするために、理解が
val result = list withFilter {
case i => go
} map {
case i => {
go = false
i
}
}
に翻訳されたので、これは、Scalaの2.8以降の場合です。前のScala 2.8は、のために、理解、次のようなものに翻訳されました:List(1, 2, 3)
は:
val r2 = list filter {
case i => go
} map {
case i => {
go = false
i
}
}
filter
を使用して、result
の値はかなり異なるだろう。 go
フラグfalse
を作成しているという事実は、フィルタが既に行われているため、フィルタには何の影響も与えません。 Scala 2.8では、withFilter
を使用してこの問題を解決しました。 withFilter
を使用すると、map
メソッド内で要素にアクセスするたびに条件が評価されます。
リファレンス: - P.120、アクションでスカラ(スカラ2.10をカバー)、マニング出版、Milanjan Raychaudhuri - 彼らはまだいくつかの日にこれらのメソッドを追加しOdersky's thoughts about for-comprehension translation
希望。 – Kigyo
@Kigyo withFilterを自分で使うとは思わない(for-expressionsの中で暗黙のうちに)。マップ/フィルタを遅延させたい場合は 'view'を使います。 –
私は参照してください。 'view'と' withFilter'の正確な違いは何ですか?なぜforループで使われないのですか? – Kigyo