Sólo quería ampliar la respuesta de mkneissl con una versión "más genérico" que debe funcionar en muchas colecciones diferentes en la biblioteca:
scala> import collection._
import collection._
scala> import generic.CanBuildFrom
import generic.CanBuildFrom
scala> def partition[X,A,B,CC[X] <: Traversable[X], To, To2](xs : CC[X])(f : X => Either[A,B])(
| implicit cbf1 : CanBuildFrom[CC[X],A,To], cbf2 : CanBuildFrom[CC[X],B,To2]) : (To, To2) = {
| val left = cbf1()
| val right = cbf2()
| xs.foreach(f(_).fold(left +=, right +=))
| (left.result(), right.result())
| }
partition: [X,A,B,CC[X] <: Traversable[X],To,To2](xs: CC[X])(f: (X) => Either[A,B])(implicit cbf1: scala.collection.generic.CanBuildFrom[CC[X],A,To],implicit cbf2: scala.collection.generic.CanBuildFrom[CC[X],B,To2])(To, To2)
scala> partition(List(1,"two", 3)) {
| case i: Int => Left(i)
| case x => Right(x)
| }
res5: (List[Int], List[Any]) = (List(1, 3),List(two))
scala> partition(Vector(1,"two", 3)) {
| case i: Int => Left(i)
| case x => Right(x)
| }
res6: (scala.collection.immutable.Vector[Int], scala.collection.immutable.Vector[Any]) = (Vector(1, 3),Vector(two))
Sólo una nota: La partición método es similar, pero tenemos que capturar algunos tipos:
X -> El tipo original para los elementos de la colección.
A -> El tipo de elementos de la partición izquierda
B -> El tipo de elementos en la partición correcta
CC -> El tipo "específico" de la colección (vector, Lista, Seq etc.) Este debe ser mayor-kinded. Probablemente podríamos evitar algunos problemas de tipo de inferencia (véase la respuesta de Adrian aquí: http://suereth.blogspot.com/2010/06/preserving-types-and-differing-subclass.html), pero me sentía perezoso;)
A -> El tipo completo de la colección en el lado izquierdo
A2 -> El tipo completo de la colección en el lado derecho
Por último, los divertidos parámetros "CanBuildFrom" son los que nos permiten construir tipos específicos, como List o Vector, genéricamente. Están integrados en todas las colecciones de la biblioteca principal.
Irónicamente, la única razón por la magia CanBuildFrom es manejar BitSets correctamente. Debido a que requiero CC para ser kinded más altos, se obtiene este mensaje de error cuando se utiliza la diversión partición:
scala> partition(BitSet(1,2, 3)) {
| case i if i % 2 == 0 => Left(i)
| case i if i % 2 == 1 => Right("ODD")
| }
<console>:11: error: type mismatch;
found : scala.collection.BitSet
required: ?CC[ ?X ]
Note that implicit conversions are not applicable because they are ambiguous:
both method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A]
and method any2Ensuring in object Predef of type [A](x: A)Ensuring[A]
are possible conversion functions from scala.collection.BitSet to ?CC[ ?X ]
partition(BitSet(1,2, 3)) {
Me marcho esta abierto para alguien para arreglar si es necesario! Veré si puedo darte una solución que funcione con BitSet después de jugar un poco más.
Lástima 'a' 'es de tipo Lista [Cualquier]' 'frente Lista [Int]' ... – huynhjl
eso es sólo porque 'x' es. Ver la respuesta de @ abhin4v. –
entiendo por qué es 'Lista [Cualquier] ', es sólo que' collect' tal como se utiliza en la pregunta devolverá una lista de '[SomeClass]' mientras partición pierde esta información. – huynhjl