2016-09-20 13 views
4

valconditionoptionの2つがあります。 conditionは、オプションの値に依存しない単純なブール値であることに注意してください。Idiomatic Sc​​ala:条件に応じたマッピングオーバーオプション

conditionが成立する場合は、結果値に変換するオプションをマップしたいと思います。それ以外の場合はdefaultResultを返信したいと思います。

これは動作し、非常に読みやすいですが、私はdefaultResultの重複を嫌い:

val result = if (condition) { 
    option.map(valueToResult).getOrElse(defaultResult) 
} else { 
    defaultResult 
} 

私の第二のアプローチは、重複を持っていませんが、私は、フィルタが実際に依存しない何かのために虐待を受けているという事実を嫌いますオプションの値について:

val result = option.filter(_ => condition).map(valueToResult).getOrElse(defaultResult) 

スカラーでもっと慣れ親しんだり、そうでなければより良いアプローチは何ですか?

+0

は、なぜあなたは 'filter'が虐待を受けていると感じていますか? 'Option [T]'の根底にある値と関係のない外部の値に基づいたフィルタリングなのですか? "基本的な' Option [T] 'のプロパティをフィルタリングするためだけに' filter'を使うという規則はありません。 "私は2番目に行くだろう。 –

+0

正確に。私は規則がないことを知っています、それは単なる個人的な(味の)味です。 – netzwerg

+0

私はあなたが何を意味するかを見ます。私はその気持ちを時々感じます。可能な代替ソリューションについては私の答えを参照してください。 –

答えて

9

あなたはOption.collectを使用することができます。

は、このオプションが空でないとpfが は、その値のために定義されている場合、この scala.Option年代含まれている値にpfを適用した結果を含むscala.Some返します。

val result = option.collect { 
    case x if condition => valueToResult(x) 
}.getOrElse(defaultResult) 
+0

これは、私の特定のシナリオで本当にうまくいきます。ありがとう! – netzwerg

+0

@netzwergよろしくお願いいたします。 –

+1

@YuvalItzchakovなぜ 'option.collect {}'の代わりに 'option match {}'をしないのですか? –

0
val result = (condition match { 
    case true => option.map(valueToResult) 
    case false => None 
}).getOrElse(defaultResult) 
1
val result = (for (v<-option if condition) yield valueToResult(v)).getOrElse(defaultResult) 
1
option.foldLeft(defaultResult)((d,x) => if (condition) valueToResult(x) else d) 
3
val result = option match { 
    case Some(value) if condition => valueToResult(value) 
    case _ => defaultResult 
} 
関連する問題