How to transform Scala collection of Option[X] to collection of X

ScalaScala CollectionsScala Option

Scala Problem Overview


I'm starting to explore Scala, and one of the things I'm intrigued by is the Option type and the promise of being able to eliminate null related errors.

However I haven't been able to work out how to transform a list (or other collection) of, say, Option[String], to a collection of String (obviously filtering out any values that are None).

In other words, how do I get from this:

List[Option[Int]] = List(Some(1))

... to this:

List[Int] = List(1)

I'm using Scala 2.8 if that has any impact on the answer.

Scala Solutions


Solution 1 - Scala

val list1 = List(Some(1), None, Some(2))
val list2 = list1.flatten // will be: List(1,2)

Solution 2 - Scala

For educational purposes, you might like some alternatives:

scala> val list1 = List(Some(1), None, Some(2))
list1: List[Option[Int]] = List(Some(1), None, Some(2))

scala> list1 flatten
res0: List[Int] = List(1, 2)

// Expanded to show the implicit parameter
scala> list1.flatten(Option.option2Iterable)
res1: List[Int] = List(1, 2)

scala> list1 flatMap (x => x)
res2: List[Int] = List(1, 2)

scala> list1 flatMap Option.option2Iterable
res3: List[Int] = List(1, 2)

// collect is a simultaneous map + filter
scala> list1 collect { case Some(x) => x }
res4: List[Int] = List(1, 2)

With Scalaz, you can perform a slightly different operation called sequence, that returns Option[List[Int]].

scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._

scala> val list1: List[Option[Int]] = List(Some(1), None, Some(2)) 
list1: List[Option[Int]] = List(Some(1), None, Some(2))

scala> list1.sequence                                              
res1: Option[List[Int]] = None

scala> val list2: List[Option[Int]] = List(Some(1), Some(2))         
list2: List[Option[Int]] = List(Some(1), Some(2))

scala> list2.sequence
res2: Option[List[Int]] = Some(List(1, 2))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnpadView Question on Stackoverflow
Solution 1 - ScalaMadocView Answer on Stackoverflow
Solution 2 - ScalaretronymView Answer on Stackoverflow