Scala: How to use reduceLeft to get the max or min value from a collection

Scala fold/reduce FAQ: Can you share an example that shows how to get the max or min value from a collection using the Scala reduceLeft collections method?

A Scala reduceLeft example

I don't have much time today, but sure, here’s a quick Scala reduceLeft example. The following code will determine which student has the max (top/high) score:

// a scala reduceLeft example

case class Student(name: String, score: Int)

object ReduceLeftExample extends App {
  
  val alex = Student("Alex", 83)
  val david = Student("David", 80)
  val frank = Student("Frank", 85)
  val julia = Student("Julia", 90)
  val kim = Student("Kim", 95)
  
  val students = Seq(alex, david, frank, julia, kim)
  
  def max(s1: Student, s2: Student): Student = if (s1.score > s2.score) s1 else s2

  val topStudent = students.reduceLeft(max)
  println(s"${topStudent.name} had the highest score: ${topStudent.score}")

}

When this code is run it will print the following output:

Kim had the highest score: 95

reduceLeft

How does reduceLeft work? If you change the max method as follows, you can see how reduceLeft works. Here's the new max method:

def max(s1: Student, s2: Student): Student = {
  println(s"comparing ${s1.name} to ${s2.name}")
  if (s1.score > s2.score) s1 else s2
}

When our test object (ReduceLeftExample) is run with this new max method, it prints the following output:

comparing Alex to David
comparing Alex to Frank
comparing Frank to Julia
comparing Julia to Kim
Kim had the highest score: 95

If you're not familiar how the reduceLeft method works, I hope this provides a really big hint.

Okay, here's a little more help: The reduceLeft method marches through the entire collection, beginning at the first element in the collection, and compares two items to each other, using the max method we passed into reduceLeft. For the first test it compares elements 0 and 1, and gets the max value between those two elements. Then it takes that max, compares it to element 2, and again determines the max between those elements. It takes that max, compares it to element 3, and so on, marching through the entire collection.

I can provide a longer, more detailed discussion in the future (if anyone wants it), but until then, I hope this has been a decent little Scala reduceLeft example.