2017-04-19 17 views
0

私はリスト[T]に変換したいいくつかのオプション[T]を持っています。私は理解のためにこれを達成しようとしている:この場合複数のオプション[T]をリスト[T]に変換する

val someOption: Option[(String, String)] = Some(("bla", "woo")) 
val anotherOption: Option[String] = None 

val result = for { 
    (a, b) <- someOption 
    c <- anotherOption 
} yield List(a, b, c) 
しかし

resultはタイプOption[List[String]]のとなりNoneが含まれています。代わりにresultのタイプがList[String]で、値がList("bla", "woo")になるようにすることができます。

編集:これは実際にはSomeOtherThing(a, b)をインスタンス化してリスト項目にするために、abを使用する必要があります。それをやっての

+0

うーん...このパズルの最も複雑な部分が分解されたコンポーネントへのあなたの 'T'から暗黙の型変換 '、Bを提供することです'。そして、それでは...あなたがコンポーネントをジェネリックな 'List'に置いたときに、あなたのコンポーネントの'型 'が失われてしまうのはどうでしょうか?暗黙のデコンストラクタが対応する型のコンポーネントに 'タグを付ける 'ようにして型を保持することもできますが、それらをgenericリストにどのように入れますか? –

+0

あなたの編集を見て、あなたは一般的な解決策を望んでおらず、この特定の場合にそれを解決しようとしています。 –

+0

だから、明確にするために、 'Option(Tuple(N))'を '' T''で 'List [T]'に変換したいのですか? –

答えて

1

一つの方法:

val someOption: Option[(String, String)] = Some(("bla", "woo")) 
val anotherOption: Option[String] = None 

val someOptionList = for { 
    (a, b) <- someOption.toList 
    v <- List(a, b) 
} yield v 

val result = someOptionList ++ anotherOption.toList 

または、中間のコレクションの構造を減らすために:

val resultIter = someOption.iterator.flatMap { 
    case (a, b) => Seq(a,b) 
} ++ anotherOption.iterator 

val result = resultIter.toList 
+0

最後の短い例 'val result = someOption.toList.flatMap {case(a、b )=> Seq(a、b)} ++ anotherOption' –

0

うーん、まあ、ユースケースはまだ私には全く明らかではありません。

しかし、ここにいくつかの考えがあります。

  • あなたのコードの問題は、理解のために、あなたは常にCollection(のような)で終わる、ということであるあなたはとてもOptionあなたのケースでは、それを起動します。

  • ++:のリストに別のCollectionを追加することは常に可能です。

ので、多分そのような何か?:

def addOptionTo(
    option: Option[(String, String)], 
    list: List[SomeOtherThing] 
): List[SomeOtherThing] = { 
    option.map { case (foo, bar) => SomeOtherThing(foo, bar) } ++: list 
} 
関連する問題