2011-10-18 54 views
99

在scala中做逆向排序的最好方法是什麼?我想象下面有點慢。在scala中反向排序的最好方法是什麼?

list.sortBy(_.size).reverse 

有沒有一種使用sortBy的方便方法,但得到一個反向排序?我寧願不需要使用sortWith

+0

的解決方案都非常不錯,但我仍然覺得你原來做這個簡單的閱讀方式。 我已經驗證了這種寫作方式存在計算缺陷,因爲您懷疑。我做了測試是這樣的: VAL時鐘=新定時器 (1至1e6.toInt).sorted(訂購[INT] .reverse) clock.addLap( 「正確的方法」) (1至1e6.toInt ).sorted.reverse clock.addLap(「wrong way」) println(clock.toString) [正確的方法,lap = 76,dur。 = 76] | [不正確的方式,圈= 326,dur。 = 250] – BlueSky

回答

175

可能有明顯的wa改變的跡象,如果你按一些數值

list.sortBy(- _.size) 

更一般地,Y的排序可以用一個隱含的排序,你可以做出明確的分類方法來完成,並訂購具有反向(不在名單下面反向) 你可以做

list.sorted(theOrdering.reverse) 

如果你想扭轉排序是隱式排序,你可以暗中得到它[訂貨[A](A你訂購的類型)或更好訂購[A]。這將是

list.sorted(Ordering[TheType].reverse) 

sortBy就像使用Ordering.by,所以你可以做

list.sorted(Ordering.by(_.size).reverse) 

也許不是最短的寫(與負),但意圖很明確

更新

最後一行不起作用。要接受Ordering.by(_.size)中的_,編譯器需要知道我們要訂購哪種類型,以便它可以鍵入_。它可能似乎是列表元素的類型,但事實並非如此,因爲排序的簽名是 def sorted[B >: A](ordering: Ordering[B])。訂購可能在A上,也可能在A的任何祖先(您可能使用byHashCode : Ordering[Any] = Ordering.by(_.hashCode))。實際上,名單是協變的這一事實迫使這個簽名。 人能做到

list.sorted(Ordering.by((_: TheType).size).reverse) 

但這是令人愉快的要少得多。

+0

超級有用 - 我不確定我是否在問一個愚蠢的問題,但我從你的答案中學到了很多東西! – schmmd

+0

除了它不起作用。當我沒有REPL方便時,我不應該回答。查看更新。 –

+0

並在輔助字段進行排序,返回一個元組:list.sortBy(x =>(-x.size,x.forTiesUseThisField))' –

7

sortBy具有提供訂購

def sortBy [B] (f: (A) ⇒ B)(implicit ord: Ordering[B]): List[A] 

所以隱含參數ord,我們可以定義自己Ordering對象

scala> implicit object Comp extends Ordering[Int] { 
| override def compare (x: Int, y: Int): Int = y - x 
| } 
defined module Comp 

List(3,2,5,1,6).sortBy(x => x) 
res5: List[Int] = List(6, 5, 3, 2, 1) 
18

易peasy(至少在size情況下):

scala> val list = List("abc","a","abcde") 
list: List[java.lang.String] = List(abc, a, abcde) 

scala> list.sortBy(-_.size) 
res0: List[java.lang.String] = List(abcde, abc, a) 

scala> list.sortBy(_.size) 
res1: List[java.lang.String] = List(a, abc, abcde) 
81
list.sortBy(_.size)(Ordering[Int].reverse) 
23

可能縮短它多了幾分:

def Desc[T : Ordering] = implicitly[Ordering[T]].reverse 

List("1","22","4444","333").sortBy(_.size)(Desc) 
1

在你通過,你可能無法通過sortWith直接修改到Arraybuffer例如功能的情況下另一種可能性:

val buf = collection.mutable.ArrayBuffer[Int]() 
buf += 3 
buf += 9 
buf += 1 

// the sort function (may be passed through from elsewhere) 
def sortFn = (A:Int, B:Int) => { A < B } 

// the two ways to sort below 
buf.sortWith(sortFn)      // 1, 3, 9 
buf.sortWith((A,B) => { ! sortFn(A,B) }) // 9, 3, 1 
6
val list = List(2, 5, 3, 1) 
list.sortWith(_>_) -> res14: List[Int] = List(5, 3, 2, 1) 
list.sortWith(_<_) -> res14: List[Int] = List(1, 2, 3, 5) 
2

兩個sortWithsortBy有一種簡潔的語法:

case class Foo(time:Long, str:String) 

val l = List(Foo(1, "hi"), Foo(2, "a"), Foo(3, "X")) 

l.sortWith(_.time > _.time) // List(Foo(3,X), Foo(2,a), Foo(1,hi)) 

l.sortBy(- _.time)   // List(Foo(3,X), Foo(2,a), Foo(1,hi)) 

l.sortBy(_.time)    // List(Foo(1,hi), Foo(2,a), Foo(3,X)) 

我發現一個與sortWith更容易理解。

0

這是我的代碼;)

VAL wordCounts = logData.flatMap(線=> line.split(」「))映射(字=>(字,1))reduceByKey((A,。。 b)=> A + b)

wordCounts.sortBy( - _._ 2).collect()以下

+0

這不是不正確的,但有趣的部分(第二行)在它之前被不需要的行淹沒了。基本上,這裏的意思是,一種做反向排序的方法是否定排序值。 –

相關問題