Scala: фильтрация коллекции опций - PullRequest
17 голосов
/ 28 сентября 2011

Скажем, у меня есть функция, которая проверяет, применима ли какая-либо операция к экземпляру A и, если да, возвращает экземпляр B или None:

   def checker[A,B]( a: A ) : Option[B] = ...

Теперь я хочу создать новую коллекциюкоторый содержит все допустимые экземпляры B, отбрасывая значения None.Следующий код, кажется, делает эту работу, но, безусловно, есть лучший способ:

   val as = List[A]( a1, a2, a3, ... )
   val bs = 
     as
     .map( (a) => checker(a) )    // List[A] => List[Option[B]]
     .filter( _.isDefined )       // List[Option[B]] => List[Option[B]]
     .map( _.get )                // List[Option[B]] => List[B]

Спасибо!

Ответы [ 2 ]

25 голосов
/ 28 сентября 2011

Это должно сделать это:

val bs = as.flatMap(checker)
11 голосов
/ 28 сентября 2011

Ответ выше верен, но если вы можете переписать checker, я предлагаю вам использовать PartialFunction и collect.PartialFunction - это функция типа A => B, которая необязательно определена для всех значений A. Вот простой пример:

scala> List(1, 2, 3, 4, "5") collect {case x : Int => x + 42}
res1: List[Int] = List(43, 44, 45, 46)

collect принимает экземпляр PartialFunction в качестве аргумента и применяет его квсе элементы коллекции.В нашем случае функция определяется только для Ints, а "5" фильтруется.Итак, collect - это комбинация map и filter, что в точности соответствует вашему случаю.

...