Scala FAQ: How can I create a range, list, or array of numbers in Scala, such as in a for
loop, or for testing purposes?
Solution
Use the to
method of the Int
class to create a Range
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 the by
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 in for
loops:
scala> for (i <- 1 to 5) println(i) 1 2 3 4 5
When creating a Range
, you can also use until
instead of to
:
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 a Range
. You can easily convert a Range
to other sequences, such as an Array
or List
, 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 as for
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 the to
and until
methods, which you’ll find in the RichInt
class. When you type the following portion of the code, you’re actually invoking the to
method of the RichInt
class:
1 to
You can demonstrate that to
is a method on an Int
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 Overflow where 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)
See Also
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |