 ## 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.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.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)