Как отфильтровать ничего из списка [Option]?

105

Если у меня есть List[Option[A]]в Scala, каков идиоматический способ отфильтровать Noneзначения?

Один из способов - использовать следующее:

val someList: List[Option[String]] = List(Some("Hello"), None, Some("Goodbye"))
someList.filter(_ != None)

Есть ли более «идиоматический» способ? Это действительно кажется довольно простым.

Ральф
источник
1
Связанный: stackoverflow.com/questions/4730842/…
dskrvk

Ответы:

161

Если вы хотите одновременно избавиться от опций, вы можете использовать flatten:

scala> someList.flatten
res0: List[String] = List(Hello, Goodbye)
Николас
источник
23
Я бы добавил, что это flatMapможет быть использовано для обработки элементов списка, отличных от Nones, аналогично тому someList.flatten.map, как часто хочется работать с этими элементами, а не только flattenсо списком из забавы.
Фрэнк
Да, я не решился спросить Рафа, что он собирается делать с отфильтрованным списком. Но есть также много сценариев, в которых вы просто хотите сгладить.
Николас
Иногда я хочу получить содержимое Optionобъектов, но в других случаях мне нужно, чтобы они остались такими же Option[A]. Я нахожу все больше и больше применений этой Option[A]классной функции.
Ральф
Есть ли эквивалентный метод типа flatForeach?
cdmckay
1
Если ваша коллекция неизменна, faltmap сделает свое дело. Если ваша коллекция изменчива, нет, это не так.
Николас
18

someList.filter(_.isDefined) если вы хотите сохранить тип результата как List[Option[A]]

Кевин О'Риордан
источник
2

В catsбиблиотеке также есть flattenOption, который превращает любой F[Option[A]]в F[A](где F[_]есть FunctorFilter)

import cats.implicits._

List(Some(1), Some(2), None).flattenOption == List(1, 2)
Dcastro
источник