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

发布于 2024-12-10 11:46:11 字数 162 浏览 0 评论 0原文

在 scala 中进行逆排序的最佳方法是什么?我想下面的速度有点慢。

list.sortBy(_.size).reverse

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

三生殊途 2024-12-17 11:46:11

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

list.sortBy(- _.size)

更一般地,排序可以通过使用隐式 Ordering 排序的方法来完成,您可以将其显式化,并且 排序有一个反向(不是下面的列表反向
如果您要反转的顺序是隐式顺序,您可以

list.sorted(theOrdering.reverse)

通过implicitly[Ordering[A]]A您要订购的类型) 或更好的Ordering[A]。这就是

list.sorted(Ordering[TheType].reverse)

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

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

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

更新

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

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

,但这并不令人愉快。

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

list.sorted(Ordering[TheType].reverse)

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

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

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

but this is much less pleasant.

何其悲哀 2024-12-17 11:46:11
list.sortBy(_.size)(Ordering[Int].reverse)
list.sortBy(_.size)(Ordering[Int].reverse)
梦途 2024-12-17 11:46:11

也许可以再缩短一点:

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

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

maybe to shorten it a little more:

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

List("1","22","4444","333").sortBy( _.size )(Desc)
泪是无色的血 2024-12-17 11:46:11

简单(至少在 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)

Easy peasy (at least in case of 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)
我的鱼塘能养鲲 2024-12-17 11:46:11

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

Both sortWith and sortBy have a compact syntax:

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 sortWith easier to understand.

软糯酥胸 2024-12-17 11:46:11
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)
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)
欢烬 2024-12-17 11:46:11

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)

sortBy has implicit parameter ord which provides ordering

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

so, we can define own Ordering object

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)
你怎么这么可爱啊 2024-12-17 11:46:11

如果你想要一个通用方法,你可以在 Scala 3 中使用它;

extension [T, A: Ordering](a: List[T])
  def sortByDesc(f: T => A) = a.sortBy(f)(Ordering[A].reverse)

If you want a generic method you can use this in Scala 3;

extension [T, A: Ordering](a: List[T])
  def sortByDesc(f: T => A) = a.sortBy(f)(Ordering[A].reverse)
街道布景 2024-12-17 11:46:11

另一种可能性是,您传递一个可能无法通过 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

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:

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
少钕鈤記 2024-12-17 11:46:11

这是我的代码;)

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

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

this is my code ;)

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

wordCounts.sortBy(- _._2).collect()
你曾走过我的故事 2024-12-17 11:46:11
val listOfIntegers = List(5, 1, 2, 4, 3)

listOfIntegers.sortBy(i=>i).reverse
val listOfIntegers = List(5, 1, 2, 4, 3)

listOfIntegers.sortBy(i=>i).reverse
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文