Каков лучший способ сортировки в скале? - PullRequest
125 голосов
/ 18 октября 2011

Какой лучший способ сделать обратную сортировку в scala? Я предполагаю, что следующее несколько медленное.

list.sortBy(_.size).reverse

Есть ли удобный способ использовать sortBy, но получить обратную сортировку? Я бы предпочел не использовать sortWith.

Ответы [ 9 ]

217 голосов
/ 18 октября 2011

Может быть очевидный способ изменить знак, если вы отсортируете по некоторому числовому значению

list.sortBy(- _.size)

В более общем смысле сортировка может быть выполнена методом, отсортированным с неявным упорядочением, которое вы можете сделать явным, и упорядочение имеет обратную сторону (не обратный список ниже) Вы можете сделать

list.sorted(theOrdering.reverse)

Если упорядочение, которое вы хотите изменить, является неявным упорядочением, вы можете получить его неявным образом [Порядок [A]] (A тип, по которому вы упорядочиваете) или лучше Порядок [A]. Это было бы

list.sorted(Ordering[TheType].reverse)

sortBy похож на использование Ordering.by, так что вы можете сделать

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

Может быть, не самое короткое, чтобы написать (по сравнению с минусом), но цель ясна

Обновление

Последняя строка не работает. Чтобы принять _ в Ordering.by(_.size), компилятору необходимо знать, какой тип мы заказываем, чтобы он мог набрать _. Может показаться, что это будет тип элемента списка, но это не так, поскольку сигнатура sorted is def sorted[B >: A](ordering: Ordering[B]). Порядок может быть на A, но также на любом предке A (вы можете использовать byHashCode : Ordering[Any] = Ordering.by(_.hashCode)). И действительно, тот факт, что список является ковариантным, заставляет эту подпись. Можно сделать

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

но это гораздо менее приятно.

102 голосов
/ 18 октября 2011
list.sortBy(_.size)(Ordering[Int].reverse)
26 голосов
/ 28 сентября 2012

возможно, чтобы сократить это немного больше:

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

List("1","22","4444","333").sortBy( _.size )(Desc)
18 голосов
/ 18 октября 2011

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)
8 голосов
/ 21 сентября 2014
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)
8 голосов
/ 18 октября 2011

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)
7 голосов
/ 10 марта 2016

Оба 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 легче понять.

1 голос
/ 15 ноября 2013

Еще одна возможность в случаях, когда вы передаете функцию, которую вы не сможете изменить напрямую в Arraybuffer через sortWith, например:

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
0 голосов
/ 18 мая 2016

это мой код;)

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

wordCounts.sortBy(- _._2).collect()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...