If I have a case class like this
case class Foo(bar: Option[String])
why does this work
scala> val l = List(Foo(Some("b")), Foo(Some("a")), Foo(Some("c")))
l: List[Foo] = List(Foo(Some(b)), Foo(Some(a)), Foo(Some(c)))
scala> l.sortBy(_.bar)
res1: List[Foo] = List(Foo(Some(a)), Foo(Some(b)), Foo(Some(c)))
but not this
scala> l.sortWith((x,y) => x.bar > y.bar)
<console>:11: error: value > is not a member of Option[String]
l.sortWith((x,y) => x.bar > y.bar)
If I want to sort a List
of Option[String]
in descending order, is it just simpler to use sortBy
and then reverse
the list?
It's because sorted
but not sortWith
takes an implicit parameter of type Ordering
, and Ordering
knows about options. With sortWith
, you're on your own. And with <
you're also on your own.
You can access the same machinery in a clunky fashion:
l.sortWith((a,b) => Ordering[Option[String]].gt(a.bar,b.bar))
or get the nicer version with an import (but now you'll be able to compare Option
s anywhere based on their contents; hopefully that is what you want):
import scala.math.Ordered._
l.sortWith((a,b) => a.bar > b.bar)
The first is such a mouthful that unless you're really pressed for performance, it's easier to just .sorted.reverse.
. (And if you are really pressed for performance, you'd probably be better off handling the option logic manually, e.g. a.bar.isEmpty || !b.bar.isEmpty || a.bar.get < b.bar.get
.)
If you're going to do multiple sorts, it's hard to beat the second for clarity. For just one test, I'd still probably favor .sorted.reverse
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With