I\'m trying to write a function which will recursively find the largest element in a list of integers. I know how to do this in Java, but can\'t understand how to do this at Sca
You could use pattern matching like that
def max(xs: List[Int]): Int = xs match {
case Nil => throw new NoSuchElementException("The list is empty")
case x :: Nil => x
case x :: tail => x.max(max(tail)) //x.max is Integer's class method
}
def max(xs: List[Int]): Int = xs match {
case Nil => throw new NoSuchElementException("empty list!")
case x :: Nil => x
case x :: tail => if (x > max(tail)) x else max(tail)
}
If you want functional approach to this problem then use reduceLeft
:
def max(xs: List[Int]) = {
if (xs.isEmpty) throw new NoSuchElementException
xs.reduceLeft((x, y) => if (x > y) x else y)
}
This function specific for list of ints, if you need more general approach then use Ordering
typeclass:
def max[A](xs: List[A])(implicit cmp: Ordering[A]): A = {
if (xs.isEmpty) throw new NoSuchElementException
xs.reduceLeft((x, y) => if (cmp.gteq(x, y)) x else y)
}
reduceLeft
is a higher-order function, which takes a function of type (A, A) => A
, it this case it takes two ints, compares them and returns the bigger one.
Folding can help:
if(xs.isEmpty)
throw new NoSuchElementException
else
(Int.MinValue /: xs)((max, value) => math.max(max, value))
List and pattern matching (updated, thanks to @x3ro)
def max(xs:List[Int], defaultValue: =>Int):Int = {
@tailrec
def max0(xs:List[Int], maxSoFar:Int):Int = xs match {
case Nil => maxSoFar
case head::tail => max0(tail, math.max(maxSoFar, head))
}
if(xs.isEmpty)
defaultValue
else
max0(xs, Int.MinValue)
}
(This solution does not create Option
instance every time. Also it is tail-recursive and will be as fast as an imperative solution.)