在 Scala 中进行逆排序的最佳方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7802851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 03:35:59  来源:igfitidea点击:

What's the best way to inverse sort in scala?

scala

提问by schmmd

What is the best way to do an inverse sort in scala? I imagine the following is somewhat slow.

在 Scala 中进行逆排序的最佳方法是什么?我想以下内容有点慢。

list.sortBy(_.size).reverse

Is there a conveinient way of using sortBy but getting a reverse sort? I would rather not need to use sortWith.

是否有一种使用 sortBy 但进行反向排序的便捷方法?我宁愿不需要使用sortWith.

回答by Didier Dupont

There may be the obvious way of changing the sign, if you sort by some numeric value

如果按某个数值排序,则可能有明显的更改符号的方法

list.sortBy(- _.size)

More generally, sorting may be done by method sorted with an implicit Ordering, which you may make explicit, and Ordering has a reverse (not the list reverse below) You can do

更一般地,排序可以通过使用隐式排序的方法进行排序,您可以明确地进行排序,并且排序有一个反向(不是下面的列表反向)你可以做

list.sorted(theOrdering.reverse)

If the ordering you want to reverse is the implicit ordering, you can get it by implicitly[Ordering[A]] (A the type you're ordering on) or better Ordering[A]. That would be

如果您要反转的排序是隐式排序,则可以通过隐式 [Ordering[A]](您正在排序的类型)或更好的 Ordering[A] 来获取它。那将是

list.sorted(Ordering[TheType].reverse)

sortBy is like using Ordering.by, so you can do

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

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

Maybe not the shortest to write (compared to minus) but intent is clear

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

Update

更新

The last line does not work. To accept the _in Ordering.by(_.size), the compiler needs to know on which type we are ordering, so that it may type the _. It may seems that would be the type of the element of the list, but this is not so, as the signature of sorted is def sorted[B >: A](ordering: Ordering[B]). The ordering may be on A, but also on any ancestor of A(you might use byHashCode : Ordering[Any] = Ordering.by(_.hashCode)). And indeed, the fact that list is covariant forces this signature. One can do

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

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

but this is much less pleasant.

但这就不那么令人愉快了。

回答by incrop

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

回答by Bruno Bieth

maybe to shorten it a little more:

也许把它缩短一点:

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

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

回答by om-nom-nom

Easy peasy (at least in case of size):

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

回答by 4e6

sortByhas implicit parameter ordwhich provides ordering

sortBy具有ord提供排序的隐式参数

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

so, we can define own Orderingobject

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

回答by Jus12

Both sortWithand sortByhave a compact syntax:

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

I find the one with sortWitheasier to understand.

我觉得sortWith比较容易理解的那个。

回答by Tomek Kozlowski

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)

回答by Chris

Another possibility in cases where you pass a function that you may not be able to modify directly to an Arraybuffer via sortWith for example:

在您传递一个您可能无法通过 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

回答by Anxo P

this is my code ;)

这是我的代码;)

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

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