map Range directly to Array

851 Views Asked by At

The following code creates a temporary Vector:

0.to(15).map(f).toArray
^^^^^^^^
Sequence
^^^^^^^^^^^^^^^
    temp Vector
^^^^^^^^^^^^^^^^^^^^^^^
                  Array

The following code creates a temporary Array:

0.to(15).toArray.map(f)
^^^^^^^^
Sequence
^^^^^^^^^^^^^^^
     temp Array
^^^^^^^^^^^^^^^^^^^^^^^
                  Array

Is there a way to map f over the Sequence and directly get an Array, without producing a temporary?

3

There are 3 best solutions below

7
On BEST ANSWER

You can use breakOut:

val res: Array[Int] = 0.to(15).map(f)(scala.collection.breakOut)

or

0.to(15).map[Int, Array[Int]](f)(scala.collection.breakOut)

or use view:

0.to(15).view.map(f).to[Array]

See this document for more details on views.

0
On
(0 to 15).iterator.map(f).toArray
0
On

If you have the hand on how to build the initial Range, you could alternatively use Array.range(start, end) from the Array companion object which creates a Range directly as an Array without cast:

Array.range(0, 15) // Array[Int] = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)

which can be mapped from an Array to an Array as such:

Array.range(0, 15).map(f) // Array[Int] = Array(0, 2, 4, 6, 8, 10, 12, 14, ...)

Note: Array.range(i, j) is an equivalent of i until j (i to j+1) and not i to j.


Even shorter and in a single pass, but less readable, using Array.tabulate:

Array.tabulate(15)(f) // Array[Int] = Array(0, 2, 4, 6, 8, 10, 12, 14, ...)