Jak łatwo konwertować z jednego typu kolekcji na inny podczas filtrowania, mapy, flatmapy w Scali?
Załóżmy, że mam List[Int]
i chcę wywołać {[1] } na każdym elemencie i odzyskać wynik jako Vector[String]
.
Jakie są różne sposoby, aby to zrobić w Scali? Czy istnieje rozwiązanie z minimalną ilością jawnego pisania? - tzn. chcę określić, że chcę Vector
zamiast List
, ale chciałbym, aby argument String
został wywnioskowany z funkcji filtra.
Czy powinienem jawnie przekazać CanBuildFrom
instancję? Skąd je wziąć-dla Seq
s, Set
S I Map
s?
1 answers
Używanie breakOut
Użyj breakOut
jako CanBuildFrom
i daj typerowi znać, jaki ma być Typ wyniku (niestety musisz podać tutaj ciąg znaków)
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)
Using to [Collection] (starting with Scala 2.10.0)
Scala 2.10.0 wprowadziła łatwy sposób konwersji kolekcji na inną kolekcję:
scala> List(1, 2, 3).map(_.toString).to[Vector]
res0: Vector[String] = Vector(1, 2, 3)
Using toIndexedSeq
Alternatywnie poproś o IndexedSeq
jawnie:
scala> res0.map(_.toString).toIndexedSeq
res4: scala.collection.immutable.IndexedSeq[String] = Vector(1, 2, 3)
Jeśli chcesz to zrobić bez tworzenie pośredniego List
, następnie:
scala> res0.view.map(_.toString).toIndexedSeq
res5: scala.collection.immutable.IndexedSeq[String] = Vector(1, 2, 3)
Wykorzystanie Naturalnych Przekształceń
Można to zrobić (niezręcznie, ale ogólniej) używając naturalnych przekształceń
scala> trait Trans[F[_], G[_]] {
| def f2g[A](f : F[A]) : G[A]
| }
defined trait Trans
Teraz podaj instancję typeklasy z listy ~ > transformacja wektorowa:
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
Zdefiniuj wrapper i konwersję implicit:
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]
Potem:
scala> List(1, 2, 3).map(_.toString).to[Vector]
res4: Vector[java.lang.String] = Vector(1, 2, 3)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-17 15:24:09