This is an excerpt from the 1st Edition of the Scala Cookbook (partially modified for the internet). This is Recipe 10.25, “How to Populate a Scala Collection with a Range”
Problem
You want to populate a Scala List
, Array
, Vector
, or other sequence with a Range
.
Solution
Call the range
method on Scala sequence classes that support it, or create a Range
and convert it to the desired sequence.
In the first approach, the range
method is available on the companion object of supported types like Array
, List
, Vector
, ArrayBuffer
, and others:
scala> Array.range(1, 5) res0: Array[Int] = Array(1, 2, 3, 4) scala> List.range(0, 10) res1: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) scala> Vector.range(0, 10, 2) res2: collection.immutable.Vector[Int] = Vector(0, 2, 4, 6, 8)
For some of the collections, such as List
and Array
, you can also create a Range
and convert it to the desired sequence:
scala> val a = (0 until 10).toArray a: Array[Int] = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) scala> val list = 1 to 10 by 2 toList list: List[Int] = List(1, 3, 5, 7, 9) scala> val list = (1 to 10).by(2).toList list: List[Int] = List(1, 3, 5, 7, 9)
The REPL shows the collections that can be created directly from a Range
:
toArray toBuffer toIndexedSeq toIterable toIterator toList toMap toSeq toSet toStream toString toTraversable
Using this approach is useful for some collections, like Set
, which don’t offer a range
method:
// intentional error scala> val set = Set.range(0, 5) <console>:7: error: value range is not a member of object scala.collection.immutable.Set val set = Set.range(0,5) ^ scala> val set = (0 until 10 by 2).toSet set: scala.collection.immutable.Set[Int] = Set(0, 6, 2, 8, 4)
You can also use a Range
to create a sequence of characters:
scala> val letters = ('a' to 'f').toList letters: List[Char] = List(a, b, c, d, e, f) scala> val letters = ('a' to 'f').by(2).toList letters: List[Char] = List(a, c, e)
As shown in many recipes, ranges are also very useful in for
loops:
scala> for (i <- 1 until 10 by 2) println(i) 1 3 5 7 9
Discussion
By using the map
method with a Range
, you can create a sequence with elements other than type Int
or Char
:
scala> val map = (1 to 5).map(_ * 2.0) map: collection.immutable.IndexedSeq[Double] = Vector(2.0, 4.0, 6.0, 8.0, 10.0)
Using a similar approach, you can also return a sequence of Tuple2
elements:
scala> val map = (1 to 5).map(e => (e,e)) map: scala.collection.immutable.IndexedSeq[(Int, Int)] = Vector((1,1), (2,2), (3,3), (4,4), (5,5))
A nice thing about that approach is that it easily converts to a Map
:
scala> val map = (1 to 5).map(e => (e,e)).toMap map: scala.collection.immutable.Map[Int,Int] = Map(5 -> 5, 1 -> 1, 2 -> 2, 3 -> 3, 4 -> 4)
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |