List.max
returns the "largest" element of a list based on some ordering... But if the list is empty you'll get a java.lang.UnsupportedOperationException: empty.max
exception. I don't really like littering code with if statements or matches or whatever. I want something like headOption
for max
, but I'm not seeing such a method. What's the most elegant way to get the equivalent of list.maxOption
?
Asked
Active
Viewed 9,174 times
13

Tomer Shetah
- 8,413
- 7
- 27
- 35

nairbv
- 4,045
- 1
- 24
- 26
-
1wouldn't that just move that if-clause somewhere else? – Daniel Figueroa Dec 09 '13 at 22:29
-
put the implementation inside a type class? – colinjwebb Dec 10 '13 at 09:43
5 Answers
15
You can convert a Try into an Option:
Try(empty.max).toOption
You can also use reduceOption (as given in scala - Min/max with Option[T] for possibly empty Seq?):
l.reduceOption(_ max _)

Community
- 1
- 1

Rob Napier
- 286,113
- 34
- 456
- 610
-
4Although this option is very elegant, in terms of performance, an `if` is vastly cheaper than opening a `try` block and possibly generating an exception with stack trace. If you case about perf, pick one of the other options. – Leif Wickland Dec 10 '13 at 00:23
-
I like all these answers, but choosing this one for the link to even more ideas. – nairbv Dec 10 '13 at 15:21
13
Or write your own:
implicit class WithMaxOption[T: Ordering](self: Seq[T]) {
def maxOption() = if(self.isEmpty) None else Some(self.max)
}
List(1,2,3).maxOption // Some(3)
List[Int]().maxOption // None

dhg
- 52,383
- 8
- 123
- 144
-
For my own education: Is there a reason to use `Seq[T]` here rather than `Traversable[T]`? – Rob Napier Dec 10 '13 at 00:59
-
-
9
Starting in Scala 2.13
, minOption
/maxOption
are now part of the standard library:
List(34, 11, 98, 56, 43).maxOption // Option[Int] = Some(98)
List[Int]().maxOption // Option[Int] = None

Xavier Guihot
- 54,987
- 21
- 291
- 190
8
Here is one way to accomplish it:
Some(list).filter(_.nonEmpty).map(_.max)

thoredge
- 12,237
- 1
- 40
- 55
1
Another formulation would be
list.headOption.map(_ => list.max)

Tim
- 26,753
- 2
- 16
- 29
-
I tend to agree!The thing to remember is that the function in a map/filter method doesn't have to use the argument that is passed to it – Tim Nov 22 '17 at 07:51