Scala排序选项

mpl*_*lis 5 scala

如果我有这样的案例类

case class Foo(bar: Option[String])
Run Code Online (Sandbox Code Playgroud)

为什么这样做

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)))
Run Code Online (Sandbox Code Playgroud)

但不是这个

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)
Run Code Online (Sandbox Code Playgroud)

如果我要排序ListOption[String]降序排列,它只是简单的使用sortBy,然后reverse在列表中?

Rex*_*err 9

这是因为sorted但不sortWith采用类型的隐式参数Ordering,并且Ordering知道选项.有了sortWith,你就是靠自己.而且<你也独自一人.

您可以以笨重的方式访问相同的机器:

l.sortWith((a,b) => Ordering[Option[String]].gt(a.bar,b.bar))
Run Code Online (Sandbox Code Playgroud)

或者通过导入获得更好的版本(但现在您可以Option根据其内容比较任何地方;希望这就是您想要的):

import scala.math.Ordered._
l.sortWith((a,b) => a.bar > b.bar)
Run Code Online (Sandbox Code Playgroud)

第一个是如此满口,除非你真的要求表现,否则更容易.sorted.reverse..(如果你真的要求性能,你可能会更好地手动处理选项逻辑,例如a.bar.isEmpty || !b.bar.isEmpty || a.bar.get < b.bar.get.)

如果你要进行多种选择,那么为了清晰起见,很难击败第二种.对于一次测试,我仍然可能会偏爱.sorted.reverse.

  • 您可以使用`import math.Ordered._`添加到答案解决方案中.在这种情况下,`l.sortWith((x,y)=> x.bar> y.bar)`按预期工作. (2认同)