得到java.util.NoSuchElementException: head of empty list
所以我试着检查一下。但现在我得到了[info] - max of a few numbers *** FAILED ***
[info] 0 did not equal 7 (ListsSuite.scala:128)
def max(xs: List[Int]): Int = {
if xs.isEmpty 0 // What can I do?
else if (xs.head > max(xs.tail)) max(xs.tail)
else max(xs.tail)
}
编辑:
对于我的class队友,提醒一下Coursera荣誉代码:
答案 0 :(得分:2)
在一般情况下,除了None
之外,您不能返回任何内容,因为一般来说空序列没有有意义的默认最大值。然而,这并不一定是这种情况;例如,您可能希望在人员列表中找到最高薪水,在这种情况下,如果列表为空,则说它为0是有意义的;但是,通常没有简单的方法来实现这样的默认值逻辑(你必须使用类型类和包装值之类的东西);现在最好的选择就是使用Option[Int]
:
def max(xs: List[Int]): Option[Int] = xs match {
case Nil => None
case x :: Nil => Some(x)
case x :: xs => Some(x max max(xs))
}
然后,您可以轻松地回到呼叫站点的默认值:
val posOrNeg = List(-5, -2, 1, 4, 10)
max(posOrNeg) // => Some(10)
val posOrNeg = List.empty[Int]
max(posOrNeg) // => None
val onlyPos = List(1, 2, 3)
max(onlyPos).getOrElse(0) // => 3
val onlyPos = List.empty[Int]
max(onlyPos).getOrElse(0) // => 0
加分:此外,您可以让max
处理任何数值列表:
def max[T: Numeric](xs: List[T]): Option[T] = xs match {
case Nil => None
case x :: Nil => Some(x)
case x :: xs => Some(x max max(xs))
}
或者实际上任何合适的数据结构都是使用比List
更通用的类型由数值组成的,但我会留给您。
但请记住:无论您选择哪种解决方案,总是尽量避免try
和异常 - 异常不符合惯用函数编程的精神(即使甚至一些库函数偶尔会出于各种原因使用它们。)
答案 1 :(得分:0)
我选择选项。
def max(xs: List[Int]) =
if xs.isEmpty None
else if (xs.head > max(xs.tail)) Some( max(xs.tail) )
else Some( max(xs.tail))
Option-Monad可以是 Some(result),意味着有结果或 None ,这意味着没有结果。如果你在 Some 中包装一些东西,你说它是结果,一切都很好。
作为替代解决方案,您可以将所有内容包装在尝试中,这将是最好的,因为空列表没有最大值,并且正确的方法是获取错误但是现在你可以以功能的方式处理它。
def max(xs: List[Int]) = Try( if (xs.head > max(xs.tail)) max(xs.tail) else xs.tail )
答案 2 :(得分:-1)
为空集合定义max元素没有意义,所以你应该返回一个sentinel值,或抛出异常(例如IllegalArgumentException)。
此外,您应该对代码进行一些更改(如果您想自己实现它,而不是使用内置的东西):
def max(list: List[Int]): Option[Int] = {
list match {
// List has no elements, so we return None
case Nil => None
// Only one element, that is the maximum
case x :: Nil => Some(x)
// Compute max(list.tail).
// If defined, it will return the greater of list.tail and list.head
case head :: tail => max(tail).map(_ max head)
}
}