在scala中进行反向排序的最佳方法是什么?我想以下情况有点慢。
list.sortBy(_.size).reverse
是否有一种方便的方法来使用sortBy但是获得反向排序?我宁愿不需要使用sortWith
。
答案 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)
sortWith
和sortBy
都有一个紧凑的语法:
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()