2011-10-31 8 views
18

ifの中の条件を特殊化することはscalaで可能ですか?私はの線に沿って考えています:Scalaの理解のための `if`ステートメント

val collection: SomeGenericCollection[Int] = ... 

trait CollectionFilter 
case object Even extends CollectionFilter 
case object Odd extends CollectionFilter 

val evenColl = for { i <- collection if(Even) } yield i 
//evenColl would be a SomeGenericEvenCollection instance 

val oddColl = for { i <- collection if(Odd) } yield i 
//oddColl would be a SomeGenericOddCollection instance 

要旨iをもたらすことで、私は潜在的に異なるタイプ(それゆえ私は「専門」としてそれを参照)の新しいコレクションを取得することである - とは対照的に、単に同じGenericCollectionタイプのフィルタリングされたバージョン。

私には分かりませんでした(例はon line 33 of this ScalaQuery exampleが見つかりました。)データベースのクエリ(つまりSELECT ... FROM ... WHERE ...)を作成してくださいクエリの結果を繰り返し処理します。

+0

この質問はあまり意味がありません。私は尋ねられていると答えたが、それを改善しようとする。 –

+0

['For expressions'](http://www.artima.com/pins1ed/for-expressions-revisited.html#23.1)が役立ちます。 – 4e6

+0

質問を明確にしようと少し追加しましたが、私が求めていたことについてあなたの考えが正しいと思われます。 – Dylan

答えて

40

私は、理解のためにifステートメントが結果タイプを変更することが可能かどうかを尋ねていると思います。 .. "

まず、for-comprehensionsがどのように拡張されるかを理解してください。 Stack Overflowには、ここで議論されている質問があり、コンパイラに渡すことができるパラメータがありますので、何が起こっているのかがわかります。 - この単純なケースでwithFilter方法は、コレクション型を変更した場合、それはあなたがやりたいだろう、だから、

val evenColl = collection.withFilter(i => Even).map(i => i) 

val evenColl = for { i <- collection if(Even) } yield i 

として翻訳さ:とにかく、このコードは

。より複雑なケースでは、それだけでは動作しません。

for { 
    x <- xs 
    y <- ys 
    if cond 
} yield (x, y) 

はどのタイプ返される場合flatMapが決定されて

xs.flatMap(ys.withFilter(y => cond).map(y => (x, y))) 

として翻訳されます。結果が返されたときに合図を受け取ると、それは機能します。

Scalaコレクションでは、フィルタを使用しても、コレクションのタイプは変更されません。しかし、それを行う独自のクラスを書くことができます。

+0

ありがとう - 私は 'withFilter'が私が欠けていた重要な情報だと思います。 – Dylan

4

はい、可能です - 簡単な例として、this tutorialを参照してください。あなたが引用したスカラークエリの例も、コレクションを反復して、そのデータを使用してクエリを構築しています。

関連する問題