2013-01-17 21 views
5

内のオプションの内部オプションから値を抽出する:は以下を考えるとScalaの

val x = Some(Some(1)) 

(1が存在しなかった場合は-1)1を取得するためのクリーンな方法は何でしょうか?

私は、データベースクエリから返されたタプルからオブジェクトインスタンスを作成しています。タプルの値の1つはこのように見えるので、ちょうど値を取得するか、パラメータを-1に設定するのに便利な短い「1つのライナー」が必要です。

答えて

15

x.flattenはあなたが探しているものです。ここでそれはあなたにSome(1)を与えるでしょう。 あなたは本当に、「1は存在しませんでした」だけでx.flatten.getOrElse(-1)を行う場合の-1を取得したい場合:

scala> Some(Some(1)).flatten.getOrElse(-1) 
res1: Int = 1 
scala> Some(None).flatten.getOrElse(-1) 
res2: Int = -1 
scala> None.flatten.getOrElse(-1) 
res3: Int = -1 
+1

平坦化を!私はそれを見た、私はそれを見た、私はそれを使用しました...今それを覚えて;-) – Jack

1

これは私が作ってみたものです:

scala> val x = Some(Some(1)) 
x: Some[Some[Int]] = Some(Some(1)) 

scala> val y = x.map(_.getOrElse(-1)).get 
y: Int = 1 

scala> val x = Some(None) 
x: Some[None.type] = Some(None) 

scala> val y = x.map(_.getOrElse(-1)).get 
y: Int = -1 

これは、最初のレベルでのみ動作しますでない場合

+0

+1それは私が取った道の一つです;-)それと、 '一致'、しかし私はそれを1つの簡単な行為で得る方法があることを知っていたが、どのように思い出すことができなかった。 Flattenは、私が探していた魔法をします。 – Jack

+0

はい、他の解決策は明らかに良いです。私はあまりにもいつも平らげを忘れる。 ;-) –

1

「ワンライナー」ではありませんが、あなたは値を抽出する関数を作ることができます。それを一般的なものにしてデフォルト値を渡すと、かなり便利になるかもしれません。

scala> def fetchFromOptions[A](default: A)(x: Option[Option[A]]) = x match { 
    | case Some(Some(a)) => a 
    | case _ => default 
    | } 
fetchFromOptions: [A](default: A)(x: Option[Option[A]])A 

scala> fetchFromOptions(-1)(Some(Some(1))) 
res0: Int = 1 

scala> fetchFromOptions(-1)(Some(None)) 
res1: Int = -1 
1

あなたが実際にそのSome(Some(1))、その後、あなたは反論できないパターンマッチ表記を使用できることがわかっている場合:

scala> val ssi1 = Some(Some(1)) 
ssi1: Some[Some[Int]] = Some(Some(1)) 

scala> val Some(Some(i1)) = ssi1 
i1: Int = 1 

ミックスの可能性Noneのいずれかがあるかもしれない場合は、あなたが使用する必要があります他の人によって示唆されたより慎重で冗長な形式。この奇妙な表記法を見つけるものについては

、あなたがmatch構築物にcaseに書いたりSome(Some(1))あるscrutinee照合するリテラルPartialFunctionたいものをと考えます。以下のため、内包

2

は、多くの場合、ネストされた構造物のこれらの種類を使用することは非常に読みやすい方法です。

val x = Some(Some(1)) 
    val result = for { 
    firstLevel <- x 
    secondLevel <- firstLevel 
    } yield { 
    // We've got an int, now transform it! 
    (secondLevel * 100).toString 
    } 

結果は、オプション[文字列]で、次の2つのいくつか(複数可)を持っているときの変換にのみ発生します。

また、パターンマッチングを使用することができます

val result2 = for { 
    Some(v) <- x 
    } yield { 
    // We've got a int, now transform it! 
    (v * 100).toString 
    } 
関連する問題