'What's the best way to inverse sort in scala?
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.
Solution 1:[1]
list.sortBy(_.size)(Ordering[Int].reverse)
Solution 2:[2]
maybe to shorten it a little more:
def Desc[T : Ordering] = implicitly[Ordering[T]].reverse
List("1","22","4444","333").sortBy( _.size )(Desc)
Solution 3:[3]
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)
Solution 4:[4]
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.
Solution 5:[5]
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)
Solution 6:[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)
Solution 7:[7]
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
Solution 8:[8]
this is my code ;)
val wordCounts = logData.flatMap(line => line.split(" "))
.map(word => (word, 1))
.reduceByKey((a, b) => a + b)
wordCounts.sortBy(- _._2).collect()
Solution 9:[9]
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)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
