novon
novon

Reputation: 993

Converting multiple Option[T] to a List[T]

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

Answers (2)

Sascha Kolberg
Sascha Kolberg

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

PH88
PH88

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

Related Questions