1. Introduction

While performing different development tasks, there are often occasions where we need to extract the individual digits from a given number.

In this tutorial, we’ll examine different ways to do this in Scala.

2. Using toString() and asDigit()

One of the simplest ways to extract the individual digits is by converting the number to a string and splitting the individual constituent characters. Let’s look at the implementation:

def getDigitsByToString(num: Long): List[Int] = {
  num.toString.map(_.asDigit).toList
}

In this method, we convert the number into a string using the toString() method. Subsequently, we iterate over each character of the string using the map() method and convert each character into a corresponding digit using the asDigit() method.

This solution is straightforward but involves conversions between different data types.

2.1. Testing the Implementation

Now that we are ready with the solution, we can write unit tests to verify the implementations. Let’s use ScalaTest to write the unit tests:

private val table = Table(
  ("Number", "Digits"),
  (987654321L, List(9, 8, 7, 6, 5, 4, 3, 2, 1)),
  (123456L, List(1, 2, 3, 4, 5, 6)),
  (1L, List(1)),
  (0L, List(0))
)
it should "get individual digits of a number using getDigitsByToString" in {
  forAll(table) { (number, digits) =>
    val result = IndividualDigits.getDigitsByToString(number)
    result shouldBe digits
  }
}

Here, we utilized the parameterized tests to write comprehensive tests for the implementations.

3. Using Division and Recursion

We can extract the individual digits by continuously dividing the number by 10 and taking the remainder. We can use recursion to perform this operation:

def getDigitsByRecursion(num: Long): List[Int] = {
  if (num < 10) {
    List(num.toInt)
  } else {
    getDigitsByRecursion(num / 10) ++ List((num % 10).toInt)
  }
}

In this approach, we extract the digit from the rightmost position using the modulo operation, which gives the remainder when divided by 10. Subsequently, we recursively invoke the same method by performing the integer division and discarding the extracted digit until the number becomes a single-digit number. This way, we can extract all the individual digits of the given number.

4. Using Division and Tail Recursion

Tail-recursion can also be used to perform this task. Tail recursion optimizes memory usage and avoids stack overflow errors for larger numbers. Let’s rewrite the previous implementation using this approach:

def getDigitsByTailRecursion(num: Long): List[Int] = {
  @tailrec
  def rec(num: Long, digits: List[Int]): List[Int] = {
    if (num < 10) {
      num.toInt :: digits
    } else {
      rec((num / 10), (num % 10).toInt :: digits)
    }
  }
  rec(num, Nil)
}

Here, we again utilize the integer division and modulo operation. However, unlike the previous implementation, this method uses tail recursion to extract the individual digits.

6. Conclusion

In this article, we discussed different ways to extract individual digits of a number. We explored the straightforward approach using the toString() method as well as the traditional division methods using both recursion and tail-recursion. Additionally, we covered the implementations using comprehensive tests.

As always, the sample code used in this article is available over on GitHub.