David Portabella David Portabella - 11 months ago 68
Scala Question

partition of a List[Try[String]] in Scala

I have a

s, and I need to partition by
s and
es, as follows:

import scala.util.{Try, Success, Failure}

val list = List(Success(10), Success(20), Failure(new Exception("error1")), Success(30))

val (listTryFailures: List[Try[Int]], listTrySuccesses: List[Try[Int]]) = list.partition(_.isFailure)
listTryFailures: List[Try[Int]] = List(Failure(java.lang.Exception: error1))
listTrySuccesses: List[Try[Int]] = List(Success(10), Success(20), Success(30))

val (listFailures: List[Throwable], listSuccesses: List[Int]) = (listTryFailures.map(_.failed.get), listTrySuccesses.map(_.get))
listFailures: List[Throwable] = List(java.lang.Exception: error1)
listSuccesses: List[Int] = List(10, 20, 30)

Is there already a function to achieve this?
(instead of calling the ugly

ps: Another option is as follows:

val listFailures: List[Throwable] = list.collect { case Failure(f) => f }
val listSuccesses: List[String] = list.collect { case Success(entry) => entry }

// or
val listFailures: List[Throwable] = list.flatMap(_.failed.toOption)
val listSuccesses: List[String] = list.flatMap(_.toOption)

but I am asking if a
(or similar name) function already exists in a standard library:

val (listFailures: List[Throwable], listSuccesses: List[Int]) = list.partitionSuccess

Answer Source

Just for completeness sake, the scalaz version, all with import scalaz._, Scalaz._:

scala> val l = List(-\/("foo"), -\/("bar"), \/-(2), \/-(4))
l: List[scalaz.\/[String,Int]] = List(-\/(foo), -\/(bar), \/-(2), \/-(4))

scala> l.separate
res7: (List[String], List[Int]) = (List(foo, bar),List(2, 4))

Also works with stdlib Try:

scala>     val list = List(Success(10), Success(20), Failure(new Exception("error1")), Success(30))
list: List[scalaz.Validation[Exception,Int]] = List(Success(10), Success(20), Failure(java.lang.Exception: error1), Success(30))

scala> list.separate
res8: (List[Exception], List[Int]) = (List(java.lang.Exception: error1),List(10, 20, 30))

Thanks to @dibblego