Jak odfiltrować Nikt nie jest poza listą [opcja]?

105

Jeśli mam List[Option[A]]w Scali, jaki jest idiomatyczny sposób na odfiltrowanie Nonewartości?

Jednym ze sposobów jest użycie:

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

Czy jest bardziej „idiomatyczny” sposób? Wydaje się to całkiem proste.

Ralph
źródło

Odpowiedzi:

161

Jeśli chcesz pozbyć się opcji w tym samym czasie, możesz użyć flatten:

scala> someList.flatten
res0: List[String] = List(Hello, Goodbye)
Nicolas
źródło
23
Dodałbym, że flatMapmożna to wykorzystać do przetworzenia elementów listy innych niż Nones, podobnie jak someList.flatten.map, ponieważ często chce się pracować z tymi elementami, a nie tylko flattenz listą dla zabawy.
Frank
Tak, wahałem się, czy zapytać Rapha, czego spodziewa się zrobić z przefiltrowaną listą. Ale jest też wiele scenariuszy, w których chcesz po prostu spłaszczyć.
Nicolas
Czasami chcę odzyskać zawartość Optionobiektów, ale innym razem potrzebuję, aby pozostały Option[A]. Znajduję coraz więcej zastosowań Option[A]- fajna funkcja.
Ralph
Czy istnieje równoważna metoda typu flatForeach?
cdmckay
1
Jeśli Twoja kolekcja jest niezmienna, faltmap załatwi sprawę. Jeśli Twoja kolekcja jest zmienna, nie, nie ma.
Nicolas
18

someList.filter(_.isDefined) jeśli chcesz zachować typ wyniku jako List[Option[A]]

Kevin O'Riordan
źródło
2

catsBiblioteka posiada również flattenOption, co zamienia każdy F[Option[A]]w produkt F[A](jeśli F[_]jest FunctorFilter)

import cats.implicits._

List(Some(1), Some(2), None).flattenOption == List(1, 2)
dcastro
źródło