2013-11-15 208 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 - 確實,這將是一個好主意。不知道爲什麼我認爲人們會想用手工的方式做到這一點。反思厭惡額外進口,也許? –