Это называется traverse
. Если вы можете использовать cats , это так просто, как:
import cats.implicits._
val result = items.traverse(foo) // Option[List[Int]]
Если нет, вы можете реализовать это довольно легко:
def traverse[A, B](data: List[A])(f: A => Option[B]): Option[List[B]] = {
@annotation.tailrec
def loop(remaining: List[A], acc: List[B]): Option[List[B]] =
remaining match {
case a :: as => f(a) match {
case Some(b) => loop(remaining = as, b :: acc)
case None => None
}
case Nil => Some(acc.reverse)
}
loop(remaining = data, acc = List.empty)
}
Что вы можете использовать например:
val result = traverse(items)(foo) // Option[List[Int]]
(однако я бы посоветовал вам использовать cats вместо этого, поскольку он более общий) .