Scala reduceLeft examples (Array, Vector)

The reduceLeft method on the Scala collections is fun. Just start with a collection:

scala> val a = Array(20, 12, 6, 15, 2, 9)
a: Array[Int] = Array(20, 12, 6, 15, 2, 9)

Then give reduceLeft a simple function to work with, and let it do its thing:

scala> a.reduceLeft(_ + _)
res0: Int = 64

scala> a.reduceLeft(_ * _)
res1: Int = 388800

scala> a.reduceLeft(_ min _)
res2: Int = 2

scala> a.reduceLeft(_ max _)
res3: Int = 20

Use a function

When your comparison operation gets long, just create a function first, then pass the function into reduceLeft:

scala> val a = Array(20, 12, 6, 15, 2, 9)
a: Array[Int] = Array(20, 12, 6, 15, 2, 9)

scala> val f = (x:Int, y:Int) => x max y
f: (Int, Int) => Int = <function2>

scala> a.reduceLeft(f)
res0: Int = 20

Admittedly that was a simple function, but we'll look at a longer one next.

How reduceLeft works

The reduceLeft method words by applying the function/operation you give it, and applying it to successive elements in the collection. The result of the first comparison is used in the second comparison, and so on. It works from left to right, beginning with the first element in the collection.

We can demonstrate this by creating a bigger function now. We'll do a max comparison like we did earlier, but now we'll add some debugging code to the function so we can see how reduceLeft works. Here's the function:

// returns the max of the two elements
def findMax(x: Int, y: Int): Int = {
  val winner = x max y
  println("compared %d to %d, %d was larger".format(x,y,winner))

Next, let's move the numbers in the array around a little bit, so the output will be more interesting:

val a = Array(12, 6, 15, 2, 20, 9)

Now we call reduceLeft on our new array, giving it our new function, and we see how reduceLeft works:

scala> a.reduceLeft(findMax)
compared 12 to 6, 12 was larger
compared 12 to 15, 15 was larger
compared 15 to 2, 15 was larger
compared 15 to 20, 20 was larger
compared 20 to 9, 20 was larger
res0: Int = 20

Boo-yah! Here's how the process worked:

  • reduceLeft started by calling findMax to test the first two elements in the array, and findMax returned 12 (because 12 is larger than 6).
  • reduceLeft took that result (12), and called findMax(12, 15). 12 was the result of the first comparison, and 15 is the next element in the collection. 15 is larger, so it became the new result.
  • reduceLeft kept taking the result from the function and comparing it to the next element in the collection, until it marched through all the elements in the collection and ended up with the number 20.
  • reduceLeft doesn't know it's finding the largest element in the collection. It just marches through the collection, using the function you provide to (a) compare one element to the next, (b) get the result, then (c) compare that result to the next element in the collection, again using your function to perform the comparison.

One subtle but important note that we just saw: Your function must return the same data type that's stored in the collection. This is necessary so reduceLeft can compare that result to the next element in the collection.

Working with other collection types

The collection can be any sequence, including List, Array, Vector, Seq, and more. The type of collection can be anything you need. For instance, determining the longest or shortest string in a collection of strings is also pretty easy:

scala> val peeps = Vector("al", "hannah", "emily", "christina", "aleka")
peeps: scala.collection.immutable.Vector[java.lang.String] = Vector(al, hannah, emily, christina, aleka)

// longest
scala> peeps.reduceLeft((x,y) => if (x.length > y.length) x else y)
res0: java.lang.String = christina

// shortest
scala> peeps.reduceLeft((x,y) => if (x.length < y.length) x else y)
res1: java.lang.String = al

Just take a similar approach with your own data types, and you can use Scala's reduceLeft collection method to handle all sorts of problems like this.


If you were wondering how Scala's reduceLeft collections method worked, I hope these examples have been helpful.