我想获得一堆列表的最大整数值。
我该怎么做?请记住,有些列表可能是空的。
我尝试了一些东西,但我得到了:
java.lang.UnsupportedOperationException: empty.max
所以我只有一堆列表:
val l1 = List.empty
val l2 = List(1,2,3)
val l3 = List(4,5,6)
val l4 = List(10)
我目前正在这样做:
(l1 ++ l2 ++ l3).max
答案 0 :(得分:4)
如果所有列表都为空,则max可能不存在,因此我们可以将结果建模为Option[Int]
。
这是一种简单的方法:
val max: Option[Int] = List(l1, l2, l3, l4).flatten match {
case Nil => None
case list => Some(list.max)
}
对List
执行操作(如果不是空的)是一个常见的用例,因此可以选择使用reduceOption
的Ad-hoc组合器,如Jean Logeart&回答:
如果你是单行,你可以这样做:
val max: Option[Int] = List(l1, l2, l3, l4).flatten.reduceOption(_ max _)
虽然我更喜欢第一个(更详细)的解决方案,因为我个人觉得它更容易阅读。
如果您希望获得默认结果,则可以从默认值开始折叠展平的List
:
val max: Int = List(l1, l2, l3, l4).flatten.foldLeft(0)(_ max _) // 0 or any default
或者,只需将0添加到原始解决方案
val max = (0 :: l1 ++ l2 ++ l3).max
答案 1 :(得分:3)
如果所有列表都可以为空:
$command=clipget()
$tempfilename="tempscript.au3"
$tempscript=FileOpen($tempfilename,2)
FileWrite($tempscript,$command)
FileFlush($tempscript)
FileClose($tempscript)
RunWait(@AutoItExe & ' /AutoIt3ExecuteScript ' & $tempfilename)
FileDelete($tempfilename)
答案 2 :(得分:1)
几乎所有其他答案都使用flatten
或flatMap
来创建中间列表。如果你的所有列表都很大,那就是不必要的内存开销。我的解决方案使用迭代器来避免中间的额外分配。
val list = List(l1, l2, l3, l4)
val max = list.iterator.flatMap(_.iterator).reduceOption(_ max _)
正如评论中所指出的,.flatMap(_.iterator)
实际上可以被flatten
取代。因为它是在迭代器上调用的,所以结果是另一个迭代器,而不是一个完整的列表。
答案 3 :(得分:0)
如果您遇到所有列表都为空的异常,那么这将解决:
(0 :: l1 ++ l2 ++ l3).max
假设你只想要默认为0,如果它们都是空的。
答案 4 :(得分:-1)
以下是一种使用选项和try
/ catch
来查找最大值的方法:
scala> val l = List(List.empty, List(1,2,3), List(4,5,6), List(10))
l: List[List[Int]] = List(List(), List(1, 2, 3), List(4, 5, 6), List(10))
scala> l.flatMap(x => try{ Some(x.max) } catch {case _ => None}).max
res0: Int = 10
根据以下评论:不要使用控制流的例外。我建议使用Gabriele Petronella's solution。