Find min and max elements of array

Following on from the other answers - a more general solution is possible, that works for other collections as well as Array, and other contents as well as Int:

def minmax[B >: A, A](xs: Iterable[A])(implicit cmp: Ordering[B]): (A, A) = {
  if (xs.isEmpty) throw new UnsupportedOperationException("empty.minmax")

  val initial = (xs.head, xs.head)

  xs.foldLeft(initial) { case ((min, max), x) => 
    (if (cmp.lt(x, min)) x else min, if (cmp.gt(x, max)) x else max) }
}                                               

For example:

minmax(List(4, 3, 1, 2, 5))              //> res0: (Int, Int) = (1,5)

minmax(Vector('Z', 'K', 'B', 'A'))       //> res1: (Char, Char) = (A,Z)

minmax(Array(3.0, 2.0, 1.0))             //> res2: (Double, Double) = (1.0,3.0)

(It's also possible to write this a bit more concisely using cmp.min() and cmp.max(), but only if you remove the B >: A type bound, which makes the function less general).


def findMinAndMax(array: Array[Int]) = { // a non-empty array

    val initial = (array.head, array.head)  // a tuple representing min-max


    // foldLeft takes an initial value of type of result, in this case a tuple
    // foldLeft also takes a function of 2 parameters.
    // the 'left' parameter is an accumulator (foldLeft -> accum is left)
    // the other parameter is a value from the collection.

    // the function2 should return a value which replaces accumulator (in next iteration)
    // when the next value from collection will be picked.

    // so on till all values are iterated, in the end accum is returned.

    array.foldLeft(initial) { ((min, max), x) => 
          if (x < min) (x, max) 
          else if (x > max) (min, x) 
          else acc 
    }
}

Here is a concise and readable solution, that avoids the ugly if statements :

def minMax(a: Array[Int]) : (Int, Int) = {
  if (a.isEmpty) throw new java.lang.UnsupportedOperationException("array is empty")
  a.foldLeft((a(0), a(0)))
  { case ((min, max), e) => (math.min(min, e), math.max(max, e))}
}

Explanation : foldLeft is a standard method in Scala on many collections. It allows to pass an accumulator to a callback function that will be called for each element of the array.

Take a look at scaladoc for further details


You can get min and max values of an Array[Int] with reduceLeft function.

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

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

scala> a.reduceLeft(_ min _)

res: Int = 2

scala> a.reduceLeft(_ max _)

res: Int = 20

See this link for more information and examples of reduceLeft method: http://alvinalexander.com/scala/scala-reduceleft-examples

Tags:

Scala