在scala中反向排序的最佳方法是什么?

时间:2011-10-18 05:37:26

标签: scala

在scala中进行反向排序的最佳方法是什么?我想以下情况有点慢。

list.sortBy(_.size).reverse

是否有一种方便的方法来使用sortBy但是获得反向排序?我宁愿不需要使用sortWith

9 个答案:

答案 0 :(得分:214)

如果按某种数值排序,可能会有一种明显的改变符号的方法

list.sortBy(- _.size)

更一般地说,排序可以通过使用隐式排序进行排序的方法来完成,您可以将其显式化,并且排序具有反向(不是下面的列表反向) 你可以做到

list.sorted(theOrdering.reverse)

如果您想要反转的顺序是隐式排序,您可以通过隐式[Ordering [A]](您订购的类型)或更好的订购[A]来获得它。那将是

list.sorted(Ordering[TheType].reverse)

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

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

也许不是最短的写(与减去相比)但意图很明显

<强>更新

最后一行不起作用。要接受_中的Ordering.by(_.size),编译器需要知道我们要排序的类型,以便它可以键入_。看起来这可能是列表元素的类型,但事实并非如此,因为sort的签名是 def sorted[B >: A](ordering: Ordering[B])。排序可以在A上,也可以在A的任何祖先上(您可以使用byHashCode : Ordering[Any] = Ordering.by(_.hashCode))。事实上,列表是协变的事实迫使这个签名。 一个人可以做到

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

但这不太令人愉快。

答案 1 :(得分:97)

list.sortBy(_.size)(Ordering[Int].reverse)

答案 2 :(得分:26)

可能会稍微缩短一点:

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

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

答案 3 :(得分:18)

容易羞怯(至少在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)

答案 4 :(得分:8)

sortBy具有隐式参数ord,它提供了排序

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

所以,我们可以定义自己的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)

答案 5 :(得分:8)

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)

答案 6 :(得分:7)

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更容易理解。

答案 7 :(得分: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

答案 8 :(得分:0)

这是我的代码;)

val wordCounts = logData.flatMap(line => line.split(" "))
                        .map(word => (word, 1))
                        .reduceByKey((a, b) => a + b)

wordCounts.sortBy(- _._2).collect()