Mike Slinn

To Converters

— Draft —

Published 2014-03-10. Last modified 2019-07-18.
Time to read: 2 minutes.

Scala has long had the to[] copy constructor, which operates on one type of collections and returns another type; Scala 2.13 changed the syntax to use parentheses: to().

The code for this lecture is provided in collections.ConverterFun.

Every Scala collection type inherits a method called to from the IterableOnce trait. The to method converts the collection to another type. This method was first mentioned in the Collections Overview lecture. Most of these conversion methods return a copy of the original data, but sometimes the data is merely wrapped, which saves processing time and memory; details vary depending on the type of collections being converted from and to. Following are some examples.

We can convert between Array and List.

Scala REPL
scala> scala> Array(1).to(List)
res1: List[Int] = List(1)
scala> scala> List(1).to(Array) res2: Array[Int] = Array(1)

... and convert from an Iterator to a List.

Scala REPL
scala> scala> val iter = io.Source.fromFile("build.sbt").getLines
iter: Iterator[String] = non-empty iterator
scala> scala> iter.to(List) res3: List[String] = List(organization := "com.micronautics", "", name := "IntermediateScala Course", "", description := "Intermediate Scala Course Notes", "", version := "0.1.1", "", scalaVersion := "2.10.4", "", autoCompilerPlugins := true, "", libraryDependencies <+= scalaVersion {, " v => compilerPlugin("org.scala-lang.plugins" % "continuations" % "2.10.4")", }, "", scalacOptions += "-P:continuations:enable", "", scalacOptions in (Compile, doc) <++= baseDirectory.map {, " (bd: File) => Seq[String](", " "-deprecation",", " "-encoding", "UTF-8",", " "-unchecked",", " "-feature",", " "-target:jvm-1.6",", " "-sourcepath", bd.getAbsolutePath,", " "-Ywarn-adapted-args",", " "-doc-source-url", "https://bitbucket.org/mslinn/course_scala_intermediate_code/src/ma...

Conversion between immutable and mutable types is possible.

Scala REPL
scala> scala> List(1).to(collection.mutable.Buffer)
res4: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1)
scala> scala> scala.collection.mutable.Buffer(1).to(List) res5: List[Int] = List(1)

Conversion between Option and List is possible.

Scala REPL
scala> scala> Some(1).to(List)
res6: List[Int] = List(1)

Here is another syntax to accomplish the same thing.

Scala REPL
scala> scala> Some(1).toList
res7: List[Int] = List(1)

You cannot convert back the other way, because Lists that have more than one element have no counterpart with Option.

Scala REPL
scala> scala> List(1).to(Option)
                  ^
       error: type mismatch;
        found   : Option.type
        required: scala.collection.Factory[Int,?]

The other convenience methods like toList are: toArray, toBuffer, toIndexedSeq, toMap, toSeq, toSet, and toVector.

Conversion between a list of tuples and an immutable.Map is also supported.

Scala REPL
scala> scala> List('a' -> 2).to(Map)
res8: scala.collection.immutable.Map[Char,Int] = Map(a -> 2)
scala> scala> List('a' -> 2).toMap // does the same thing res9: scala.collection.immutable.Map[Char,Int] = Map(a -> 2)
scala> scala> Map('a' -> 2).toList res10: List[(Char, Int)] = List((a,2))

We can convert a Vector to a LazyList like this.

Scala REPL
scala> scala> Vector(1, 1, 2, 2, 3, 3).to(LazyList)
res11: scala.collection.immutable.LazyList[Int] = LazyList(?)

This is rather like making a view, which converts a strict collection into a lazy collection.

Scala REPL
scala> scala> Vector(1, 1, 2, 2, 3, 3).view
res12: scala.collection.IndexedSeqView[Int] = IndexedSeqView(<not computed>)

The documentation I linked to is old and has not yet been updated. Let's see what happens when we try to convert from a view back to a strict list by using the force method.

Scala REPL
scala> scala> Vector(1, 1, 2, 2, 3, 3).view.force
                                     ^
       warning: method force in trait View is deprecated (since 2.13.0): Views no longer know about their underlying collection type; .force always returns an IndexedSeq
res1: scala.collection.IndexedSeq[Int] = Vector(1, 1, 2, 2, 3, 3)

We can ask for the type of collection that we want, however.

Scala REPL
scala> scala> Vector(1, 1, 2, 2, 3, 3).view.toVector
res13: scala.collection.immutable.Vector[Int] = Vector(1, 1, 2, 2, 3, 3)

Lots more conversions are possible.

Scala REPL
scala> scala> List(1).to(Set)
res14: scala.collection.immutable.Set[Int] = Set(1)
scala> scala> List(1).toSet // does the same thing res15: scala.collection.immutable.Set[Int] = Set(1)
scala> scala> Set(1).toList res16: List[Int] = List(1)
scala> scala> Set(1).to(scala.collection.immutable.BitSet) res17: scala.collection.immutable.BitSet = BitSet(1)
scala> scala> Array(1).to(scala.collection.immutable.BitSet) res18: scala.collection.immutable.BitSet = BitSet(1)

... and many more! In fact, any collection that implements the scala.collection.Factory trait supports the to method.

We talked about parallel collections in the Parallel Collections lecture. Here is how to convert from a single-threaded immutable.List to a multithreaded set (ParSet).

Scala REPL
scala> scala> val parSet = List(1, 1, 2, 2, 3, 3).to(scala.collection.parallel.ParSet)
parSet: scala.collection.parallel.ParSet[Int] = <function1>
scala> scala> parSet.sum res19: Int = 6

The above only works if the scala-parallel-collections library is a dependency of the sbt project.

Iterable also provides a toParArray method for the special case of converting Arrays to parallel arrays. As we saw in the Parallel Collections lecture, Iterable's par method converts collection subclasses to parallel versions of those collections, instead of defining dozens of toParXXX methods.


* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.