1. Introduction

Range is one of the more interesting features in Scala. In this tutorial, we’ll learn more about Range, ways to create a Range, and some of its supported methods.

2. Creating Range

Range is a datatype that represents an ordered collection of numbers. We can create a Range for positive, negative, and decimal values. We can also iterate over a Range using most of the collection methods like map, filter, and foreach. Let’s see how we can create ranges.

2.1. Using Companion Object

We can create a Range by providing the start and end values to the Range.inclusive method. Let’s see how we can create a range of integers from 1 to 10:

val rangeIncl = Range.inclusive(1,10)
rangeIncl.toList shouldBe List(1,2,3,4,5,6,7,8,9,10)

The rangeIncl will contain values from 1 to 10, inclusive of both 1 and 10.

If we want to create a range by excluding the end value, we can use:

val rangeExcl = Range(1,10)
rangeExcl.toList shouldBe List(1,2,3,4,5,6,7,8,9)

Now, the rangeExcl will contain values from 1 to 9 only, by excluding the end value 10.

2.2. Using to and until Methods

We can also create ranges by using the methods to and until:

val rangeTo = 1 to 10
rangeTo.toList shouldBe List(1,2,3,4,5,6,7,8,9,10)

The above expression is precisely the same as Range.inclusive(1,10).

Similarly, an exclusive range can be created using until:

val rangeUntil = 1 until 10
rangeUntil.toList shouldBe List(1,2,3,4,5,6,7,8,9)

3. Range With Step

When we create a Range, the default step value is 1. That means, between any two consecutive values in a range, the difference will always be 1. We can also create a range with a different step value using the keyword by. For example, we can create a range of odd numbers from 1 to 100 using:

val oddRange = 1 to 100 by 2
oddRange.head shouldBe 1
oddRange.last shouldBe 99

Similarly, we can also create a range with step value using the companion object. For example, to create a range of odd numbers from 1 to 10:

val rangeStep = Range(1,10,2)
rangeStep.toList shouldBe List(1,3,5,7,9)

We can also provide the step as negative numbers:

val reverseRange = 20 to 1 by -2
reverseRange.head shouldBe 20
reverseRange.last shouldBe 2

The variable reverseRange will contain even numbers from 20 to 2, in descending order.

What if we use step value 2 instead of -2 in reverseRange? The resultant range will be empty since it is not possible to start at 20 and reach 1 by using a positive number as a step.

Similarly, we can also create a range of negative numbers:

val negativeRange = -1 to -10 by -2
negativeRange.toList shouldBe List(-1,-3,-5,-7,-9)

4. Non-Integer Range

So far, we’ve seen ranges with Integer numbers. We can also create a range for Decimal numbers. But, for decimal range, we must provide the step value explicitly:

val doubleRange = 1.0 to 2.0 by 0.2

This will create a range with values as [1.0, 1.2, 1.4, 1.6, 1.8, 2.0]. However, this way of using Double values to build a range is deprecated since Scala 2.12.6, mainly due to the decimal point approximation issues. It is suggested to use BigDecimal instead of Double to create such a range:

val decimalRange = BigDecimal(1.0) to BigDecimal(2.0) by 0.2
decimalRange shouldBe List(1.0,1.2,1.4,1.6,1.8,2.0)

5. Useful Methods on Range

Most of the methods applicable to collections are also applicable to Range. Let’s see some of the most useful methods that can be applied.

5.1. Iterate and Filter

We can use map, foreach, filter, and filterNot to iterate and filter through a range. All these methods are inherited from the trait TraversableLike. We can also convert a Range to a List by using the toList method.

val range = 1 to 10 

val evenNumbers = range.filter(_ % 2 == 0) 
evenNumbers shouldBe List(2,4,6,8,10)

val mappedRange = range.map(n => n*2) 
mappedRange shouldBe List(2,4,6,8,10,12,14,16,18,20)

5.2. Take and Drop

Range also provides additional methods like drop, take, dropWhile, and takeWhile, all of which return another Range.

val range = 1 to 10

val take2:Range = range.take(2) 
take2.head shouldBe 1
take2.last shouldBe 2

val drop5:Range = range.drop(5)
drop5.head shouldBe 6
drop5.last shouldBe 10

6. Conclusion

In this tutorial, we’ve learned about the Range in Scala and some of the common methods that can be applied. All the sample code used in this tutorial is available as unit tests over on GitHub.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.