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


105

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

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

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

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


Ответы:


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 сделает свое дело. Если ваша коллекция изменчива, нет, это не так.
Николас


2

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

import cats.implicits._

List(Some(1), Some(2), None).flattenOption == List(1, 2)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.