Reputation: 993
I have several Option[T] that I would like to convert to a List[T]. I'm attempting to achieve this with a for comprehension:
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)
However result
in this case becomes of type Option[List[String]]
and contains None
. How can I instead have result
become of type List[String]
with a value of List("bla", "woo")
.
Edit: This is a contrived example, in reality I need to use a
and b
to instantiate SomeOtherThing(a, b)
and have that be a list item.
Upvotes: 0
Views: 108
Reputation: 7162
Hmm, well, the use case is still not absolutely clear to me.
However, here are some thoughts.
The issue with your code is that, in a for comprehension, you always end up with the Collection
(like) you start it, so in your case Option
.
There is always the possibility to just prepend another Collection
to a list with ++:
.
So, maybe something like that?:
def addOptionTo(
option: Option[(String, String)],
list: List[SomeOtherThing]
): List[SomeOtherThing] = {
option.map { case (foo, bar) => SomeOtherThing(foo, bar) } ++: list
}
Upvotes: 0
Reputation: 1806
One way of doing it:
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
or, to reduce constructions of intermediate collections:
val resultIter = someOption.iterator.flatMap {
case (a, b) => Seq(a,b)
} ++ anotherOption.iterator
val result = resultIter.toList
Upvotes: 1