Is there any method that does the same thing as map() but generates a different type of container?

scala, scala-collections

Solution

Have a look at the full signature for `map`:

def map[B, That](f: (A) ⇒ B)(implicit bf: CanBuildFrom[List[A], B, That]): That

The key to this is the implicit `CanBuildFrom`, which governs how the result collection is generated from the input collection. We can replace the implicit `CanBuildFrom` with an explicit one that allows us to build a different result collection.

Even better, we don't even have to write this explicit method! It's there already, in the form of `scala.collection.breakOut`. From the ScalaDoc:

Provides a CanBuildFrom instance that builds a specific target collection (To') irrespective of the original collection (From').

So if we pass in `collection.breakOut`, we can then specify exactly what we want to the `map` method:

val x = IndexedSeq(1,2,3,4,5)
x.map[Int, List[Int]](_ * 2)(collection.breakOut)
> res6: List[Int] = List(2, 4, 6, 8, 10) 

Problem

Sometimes I need to create a collection by mapping another one with different type. For example, some function needs `List[_]` as its parameter type, but I need to produce that by mapping a `IndexedSeq[_]`: ``` val r = (1 to n).map { ... } someFunction(r.toList) ``` Although I can fulfill that by calling `IndexedSeq[_]`'s `map` method first followed by another call to `toList`, this produces a redundant intermediate collection. Is there any way to avoid this redundant step while still keeping code concise?

Original source

Related problems