Reputation: 32264
If I have a List[Option[A]]
in Scala, what is the idiomatic way to filter out the None
values?
One way is to use the following:
val someList: List[Option[String]] = List(Some("Hello"), None, Some("Goodbye"))
someList.filter(_ != None)
Is there a more "idiomatic" way? This does seem pretty simple.
Upvotes: 130
Views: 63907
Reputation: 9464
If you had a list of options of an object which is more complex than a string like so:
case class Thing(name: String, number: Int)
val someSequence: Seq[Option[Thing]] = Seq(
Some(Thing("Hello", 1)),
None,
Some(Thing("Goodbye", 2)),
None
)
you can use flatMap to chain the mapping of the inner value:
scala> someSequence.flatMap(_.map(_.name))
val res2: Seq[String] = List(Hello, Goodbye)
But in my opinion @Nicolas' answer above is cleaner because you would be able to do:
scala> someSequence.flatten.map(_.name)
val res3: Seq[String] = List(Hello, Goodbye)
Upvotes: 0
Reputation: 68640
The cats
library also has flattenOption
, which turns any F[Option[A]]
into an F[A]
(where F[_]
is a FunctorFilter
)
import cats.implicits._
List(Some(1), Some(2), None).flattenOption == List(1, 2)
Upvotes: 5
Reputation: 229
someList.filter(_.isDefined)
if you want to keep the result type as List[Option[A]]
Upvotes: 22
Reputation: 24759
If you want to get rid of the options at the same time, you can use flatten
:
scala> someList.flatten
res0: List[String] = List(Hello, Goodbye)
Upvotes: 195