If you have ever wondered how the range works in for(i <- 1 to 5 by 2) print(i), you will come to know about it in this article. This is coming from a class called Range. We will see examples of Range, to, until and by methods.
Let’s start with a simple example and then we will build on it.

## Example of Range

A Range class represents integer values in range.

For example, Range(1, 10, 2) will covers a range of values starting from 1, with a step value of 2 until 10.

RangeExample.scala:

object RangeExample {
val range = Range(1, 10, 1)
println("Range object: " + range)
def main(args: Array[String]): Unit = {
}
}

Notice 10 is left out, as by default, range excludes the end value.

Output:

Range object: Range(1, 2, 3, 4, 5, 6, 7, 8, 9)

If you have noticed, to create a new range, we don’t call new Range(start, end, step). Instead, we call just Range(start, end, step). Internally, scala converts it into Range.apply(start, end, step). Any object that has an apply method can be called with the .apply omitted.

def apply(start: Int, end: Int, step: Int): Range = new Range(start, end, step)

## Example of Inclusive Range

Let’s use the inclusive method to include the end value.

object RangeExample {
val range = Range(1, 10, 1)
println("Range object: " + range)

println("Range inclusive of end: " + Range.inclusive(1, 10, 1))
def main(args: Array[String]): Unit = {
}
}

Output:

## Default Step

Range object: Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
Range inclusive of end: Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
step if your step value is just 1.
object RangeExample {
val range = Range(1, 10, 1)
println("Range object: " + range)

println("Range inclusive of end: " + Range.inclusive(1, 10, 1))

println("Range with default step: " + Range(1, 10))
def main(args: Array[String]): Unit = {
}
}

Output:

Range object: Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
Range inclusive of end: Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Range with default step: Range(1, 2, 3, 4, 5, 6, 7, 8, 9)

## Example of Negative Step

Let’s now try out a negative step, with value starting at 10, step -1 until the end at 1.

object RangeExample {
val range = Range(1, 10, 1)
println("Range object: " + range)

println("Range inclusive of end: " + Range.inclusive(1, 10, 1))

println("Range with default step: " + Range(1, 10))

println("Range with negative step: " + Range(10, 1, -1))
def main(args: Array[String]): Unit = {
}
}

Output:

Range object: Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
Range inclusive of end: Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Range with default step: Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
Range with negative step: Range(10, 9, 8, 7, 6, 5, 4, 3, 2)

## Example of foreach on Range

Print the range of values using foreach.

object RangeExample {
val range = Range(1, 10, 1)
println("Range object: " + range)

println("Range inclusive of end: " + Range.inclusive(1, 10, 1))

println("Range with default step: " + Range(1, 10))

println("Range with negative step: " + Range(10, 1, -1))

print("Print range using foreach: ")
range.foreach {print}
def main(args: Array[String]): Unit = {
}
}

Output:

Range object: Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
Range inclusive of end: Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Range with default step: Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
Range with negative step: Range(10, 9, 8, 7, 6, 5, 4, 3, 2)
Print range using foreach: 123456789

## ‘to’, ‘until’ and ‘by’ functions

If you want a range of integer values, you can also use the to method. For example:

NumberRangeExample.scala:

object NumberRangeExample {
println("Get range from integer: " + (1).to(3))
def main(args: Array[String]): Unit = {
}
}

Output:

Get range from integer: Range(1, 2, 3)

Let’s try this with some fractions.

object NumberRangeExample {
println("Get range from integer: " + (1).to(3))
println("Get range from integer: " + (1.2).to(3, .2))
def main(args: Array[String]): Unit = {
}
}

Output:

Get range from integer: NumericRange(1.2, 1.4, 1.5999999999999999, 1.7999999999999998, 1.9999999999999998, 2.1999999999999997, 2.4, 2.6, 2.8000000000000003, 3.0000000000000004)

You can also use the range in for loop without the brackets, by assigning a step value . For example:

object NumberRangeExample {
println("Get range from integer: " + (1).to(3))
println("Get range from integer: " + (1.2).to(3, .2))

for (i <- 1 to 5 by 2) print(i)
def main(args: Array[String]): Unit = {
}
}

Output:

Get range from integer: Range(1, 2, 3)
Get range from integer: NumericRange(1.2, 1.4, 1.5999999999999999, 1.7999999999999998, 1.9999999999999998, 2.1999999999999997, 2.4, 2.6, 2.8000000000000003, 3.0000000000000004)
135

Method to returns range inclusive of the end value. If you want to exclude the end value, use until.

object NumberRangeExample {
println("Get range from integer: " + (1).to(3))
println("Get range from integer: " + (1.2).to(3, .2))

for (i <- 1 to 5 by 2) print(i)
println
for (i <- 1 until 6) print(i)
def main(args: Array[String]): Unit = {
}
}

Output:

Get range from integer: Range(1, 2, 3)
Get range from integer: NumericRange(1.2, 1.4, 1.5999999999999999, 1.7999999999999998, 1.9999999999999998, 2.1999999999999997, 2.4, 2.6, 2.8000000000000003, 3.0000000000000004)
135
123456

## Example of Range Functions

You can also call some functions on the range. For example, sum, tail, size, drop:

object NumberRangeExample {
println("Get range from integer: " + (1).to(3))
println("Get range from integer: " + (1.2).to(3, .2))

for (i <- 1 to 5 by 2) print(i)
println
for (i <- 1 until 6) print(i)
println

//one functions on range
val sumOfNumbersInRange = 1 to 3 sum
val tailRange = 1 to 3 tail
val sizeOfRange = 1 to 3 size
val dropElementsCreateNewRange = 1 to 3 drop 2

println("sumOfNumbersInRange: " + sumOfNumbersInRange)
println("tailRange: " + tailRange)
println("sizeOfRange: " + sizeOfRange)
println("dropElementsCreateNewRange: " + dropElementsCreateNewRange)

def main(args: Array[String]): Unit = {
}
}

tail removes the head and returns rest of the elements as a new Range
drop drops the number of elements mentioned and returns the remaining elements as a new range.

Output:

Get range from integer: Range(1, 2, 3)
Get range from integer: NumericRange(1.2, 1.4, 1.5999999999999999, 1.7999999999999998, 1.9999999999999998, 2.1999999999999997, 2.4, 2.6, 2.8000000000000003, 3.0000000000000004)
135
12345
sumOfNumbersInRange: 6
tailRange: Range(2, 3)
sizeOfRange: 3
dropElementsCreateNewRange: Range(3)