2013-11-15 153 views
3

如果我有一个案例类这样斯卡拉排序选项

​​

为什么这项工作

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))) 

,但不是这个

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) 

如果我要排序的ListOption[String]按降序排列,使用sortBy然后更简单的列表?

回答

8

这是因为sorted而不是sortWith采取Ordering类型的隐式参数,并且Ordering知道选项。与sortWith,你是你自己的。与<你也是你自己。

你可以在一个笨重的方式访问相同的机器:

l.sortWith((a,b) => Ordering[Option[String]].gt(a.bar,b.bar)) 

或获得与进口更好的版本(但现在你就可以根据自己的内容比较Option小号的任何地方;希望这是你想要的):

import scala.math.Ordered._ 
l.sortWith((a,b) => a.bar > b.bar) 

首先是这样一个拗口,除非你真的压性能的时候,它更容易只是.sorted.reverse.。 (如果你对性能有很高的要求,那么你最好手动处理选项逻辑,例如a.bar.isEmpty || !b.bar.isEmpty || a.bar.get < b.bar.get。)

如果你打算做多种排序,为了清晰起见,很难打败第二个排序。对于一次测试,我仍然可能倾向于.sorted.reverse

+2

您可以使用'import math.Ordered._'添加您的答案解决方案。在这种情况下,'l.sortWith((x,y)=> x.bar> y.bar)'按预期工作。 – senia

+0

@senia - 确实,这将是一个好主意。不知道为什么我认为人们会想用手工的方式做到这一点。反思厌恶额外进口,也许? –