Ralph
Ralph

Reputation: 32264

How to filter None's out of List[Option]?

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

Answers (4)

Daniel
Daniel

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

dcastro
dcastro

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

Kevin O'Riordan
Kevin O'Riordan

Reputation: 229

someList.filter(_.isDefined) if you want to keep the result type as List[Option[A]]

Upvotes: 22

Nicolas
Nicolas

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

Related Questions