How to create a Range, List, or Array of numbers in Scala
Scala FAQ: How can I create a range, list, or array of numbers in Scala, such as in afor
loop, or for testing purposes?
Solution
Use theto
method of theInt
class to create aRange
with the desired elements:
scala> val r = 1 to 10
r: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
You can also set the step with theby
method:
scala> val r = 1 to 10 by 2
r: scala.collection.immutable.Range = Range(1, 3, 5, 7, 9)
scala> val r = 1 to 10 by 3
r: scala.collection.immutable.Range = Range(1, 4, 7, 10)
Note that ranges are commonly used infor
loops:
scala> for (i <- 1 to 5) println(i)
1
2
3
4
5
When creating aRange
, you can also useuntil
instead ofto
:
scala> for (i <- 1 until 5) println(i)
1
2
3
4
Discussion
Scala makes it easy to create a range of numbers. The first three examples shown in the Solution create aRange
. You can easily convert aRange
to other sequences, such as anArray
orList
, like this:
scala> val x = 1 to 10 toArray
x: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> val x = 1 to 10 toList
x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Although this_infix notation_syntax is clear in many situations (such asfor
loops), it’s generally preferable to use this syntax:
scala> val x = (1 to 10).toList
x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> val x = (1 to 10).toArray
x: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
The magic that makes this process work is theto
anduntil
methods, which you’ll find in theRichInt
class. When you type the following portion of the code, you’re actually invoking theto
method of theRichInt
class:
1 to
You can demonstrate thatto
is a method on anInt
by using this syntax in the REPL:
1.to(10)
Although the infix notation (1 to 10
) shown in most of these examples can make your code more readable,Rahul Phulore has a post on Stack Overflowwhere he advises against using it for anything other than internal DSLs.
Combine this with Recipe 2.7 of the Scala Cookbook, “Generating Random Numbers,” and you can create a_random length_range, which can be useful for testing:
scala>var range = 0 to scala.util.Random.nextInt(10)
range: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3)
By using a range with the for/yield construct, you don’t have to limit your ranges to sequential numbers:
scala> for (i <- 1 to 5) yield i * 2
res0: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)
You also don’t have to limit your ranges to just integers:
scala> for (i <- 1 to 5) yield i.toDouble
res1: scala.collection.immutable.IndexedSeq[Double] = Vector(1.0, 2.0, 3.0, 4.0, 5.0)