Baeldung Pro – Scala – NPI EA (cat = Baeldung on Scala)
announcement - icon

Learn through the super-clean Baeldung Pro experience:

>> Membership and Baeldung Pro.

No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.

1. Introduction

In this tutorial, we’ll look at different ways to calculate the sum of a list of numbers in Scala.

2. Using sum()

Scala’s standard library includes a convenient sum() method, which can be used on any iterable collection type, such as List, Vector, and Array. Let’s look at how to use this on a List[Int]:

List(1,2,3,4).sum shouldBe 10

This is the most straightforward way to calculate the sum.

3. Using foldLeft()

Another approach to calculate the sum is using the foldLeft() function on the collection:

def sumByFold(list: List[Int]): Int = list.foldLeft(0)(_ + _)
sumByFold(List(1,2,3,4)) shouldBe 10

We used the initial value of 0 and then applied the plus operation on each element to calculate the total sum.

This method allows for more flexibility in manipulating the list. For example, we can extract a specific field from a collection of objects and calculate the sum of those fields:

case class Item(price: Int)
val items = List(Item(1), Item(2), Item(3), Item(4))
items.foldLeft(0)((acc, item) => acc + item.price) shouldBe 10

In the code above, we extracted the price field within a case class and calculated the total sum using the foldLeft().

4. Using reduce()

We can also use the reduce() method to calculate the sum of a list in Scala. Let’s look at an example:

List(1,2,3,4).reduce(_ + _) shouldBe 10

This approach is even shorter than using the foldLeft() function. However, applying the reduce operation on an empty list throws an exception at runtime.

Scala also offers a variant of the reduce method called reduceOption(), which avoids exceptions by returning an Option type. If the list is empty, it returns None instead of throwing an error, making it safer to use in situations where the list may be empty:

List.empty[Int].reduceOption(_ + _).getOrElse(0) shouldBe 0

In this example, we use getOrElse() to return a default value of zero if the list is empty.

5. Using Tail Recursion

Tail recursion is another approach to calculating the total sum of a list. Let’s look at the implementation:

def sumByTailRecursion(list: List[Int]): Int = {
  @tailrec
  def rec(list: List[Int], sum: Int): Int = {
    list match {
      case Nil       => sum
      case a :: tail => rec(tail, sum + a)
    }
  }
  rec(list, 0)
}

We defined a recursive function that accumulates the sum as it processes each element, ensuring the recursion is in the tail position. This allows the Scala compiler to optimize the function and avoid stack overflows for large lists.

6. Using Iteration

So far, we’ve explored the functional approach using immutable variables. Alternatively, we can calculate the sum by iterating through each element and accumulating the result in a mutable variable. This can be done using the foreach() function to process each element and update the sum:

var sum = 0
List(1,2,3,4).foreach(num => sum += num)
sum shouldBe 10

Alternatively, we can use for-loop to achieve the same result:

var sum = 0
val list = List(1, 2, 3, 4)
for (num <- list) { sum += num }
sum shouldBe 10

This approach offers a simple and imperative solution for summing elements in a list using a traditional for-loop.

7. Sum Calculation with Generic Types

In the previous sections, we focused on implementing the sum function specifically for the List[Int] type. However, we can also create a generic function that calculates the sum of a list containing any numeric values, allowing for greater flexibility and reusability across different numeric types. Let’s look at the implementation:

def sumNumeric[T](list: List[T])(using numeric: Numeric[T]): T = {
  list.sum
}

This function takes a generic list and uses an implicit Numeric instance to compute the sum of its elements, allowing for the seamless aggregation of values across various numeric types.

Now, we can utilize this method for any type that has a corresponding Numeric typeclass instance, including Int, Long, Double, and others:

val ints = List(1, 2, 3, 4)
sumNumeric(ints) shouldBe 10
sumNumeric(List.empty[Int]) shouldBe 0
val doubles = List(1d, 2d, 3d, 4d)
sumNumeric(doubles) shouldBe 10d
val bigints = List(BigInt(1), BigInt(2), BigInt(3), BigInt(4))
sumNumeric(bigints) shouldBe BigInt(10)

As we can see, this approach enables versatile calculations across various numeric data types.

8. Conclusion

In this article, we explored various methods for calculating the sum of a list of numbers in Scala. We examined built-in functions, functional approaches like foldLeft() and reduce(), and simple iterative techniques. Additionally, we implemented a method to calculate the sum of a generic list using the Numeric typeclass, showcasing Scala’s flexibility in handling different numeric types.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.