examples example ejemplo and scala collections map filter implicit-conversion

example - ¿Cómo puedo convertir fácilmente de un tipo de colección a otro durante un filtro, mapa, flatMap en Scala?



java flat (1)

Supongamos que tengo una List[Int] y quiero llamar a toString en cada elemento y obtener el resultado como Vector[String] .

¿Cuáles son las diversas formas de hacer esto en Scala? ¿Hay una solución con una cantidad mínima de tipeo explícito? - es decir, quiero especificar que quiero un Vector lugar de una List , pero me gustaría que el argumento String se infiera de la función de filtro.

¿O debería pasar explícitamente una instancia de CanBuildFrom ? ¿De dónde los obtengo - para Seq s, Set sy Map s?


Usando BreakOut

Use breakOut como CanBuildFrom y deje que el tipeador sepa cuál es su tipo de resultado (desafortunadamente debe especificar Cadena aquí)

scala> import collection.breakOut import collection.breakOut scala> List(1, 2, 3) res0: List[Int] = List(1, 2, 3) scala> res0.map(_.toString)(breakOut) : Vector[String] res2: Vector[String] = Vector(1, 2, 3)

Uso de [Colección] (comenzando con Scala 2.10.0)

Scala 2.10.0 introdujo una forma fácil de convertir una colección a otra colección:

scala> List(1, 2, 3).map(_.toString).to[Vector] res0: Vector[String] = Vector(1, 2, 3)

Usando toIndexedSeq

Alternativamente, solicite un IndexedSeq explícitamente:

scala> res0.map(_.toString).toIndexedSeq res4: scala.collection.immutable.IndexedSeq[String] = Vector(1, 2, 3)

Si quiere hacer esto sin crear la List intermedia, entonces:

scala> res0.view.map(_.toString).toIndexedSeq res5: scala.collection.immutable.IndexedSeq[String] = Vector(1, 2, 3)

Usando transformaciones naturales

Podrías hacerlo (torpemente, pero de manera más general) usando transformaciones naturales

scala> trait Trans[F[_], G[_]] { | def f2g[A](f : F[A]) : G[A] | } defined trait Trans

Ahora proporcione una instancia de clase de clase de la transformación List ~> Vector:

scala> implicit val List2Vector = new Trans[List, collection.immutable.Vector] { | def f2g[A](l : List[A]) : Vector[A] = l.map(identity[A])(collection.breakOut) | } List2Vector: java.lang.Object with Trans[List,scala.collection.immutable.Vector] = $anon$1@56329755

Definir un contenedor y una conversión implícita:

scala> class Clever[M[_], A](ma : M[A]) { def to[N[_]](implicit t : Trans[M, N]) : N[A] = t.f2g(ma) } defined class Clever scala> implicit def ma2clever[M[_], A](ma : M[A]) = new Clever[M, A](ma) ma2clever: [M[_],A](ma: M[A])Clever[M,A]

Entonces:

scala> List(1, 2, 3).map(_.toString).to[Vector] res4: Vector[java.lang.String] = Vector(1, 2, 3)