Apa cara terbaik untuk melakukan pengurutan terbalik dalam skala? Saya membayangkan berikut ini agak lambat.
list.sortBy(_.size).reverse
Apakah ada cara yang mudah untuk menggunakan sortBy tetapi mendapatkan pengurutan terbalik? Saya lebih suka tidak perlu menggunakan sortWith
.
Jawaban:
Mungkin ada cara yang jelas untuk mengubah tanda, jika Anda mengurutkan berdasarkan beberapa nilai numerik
Secara lebih umum, pengurutan dapat dilakukan dengan metode yang diurutkan dengan Pengurutan implisit, yang dapat Anda buat secara eksplisit, dan Pengurutan memiliki kebalikan (bukan daftar terbalik di bawah). Anda dapat melakukannya
Jika pengurutan yang ingin Anda balikkan adalah pengurutan implisit, Anda bisa mendapatkannya dengan [Pengurutan [A]] secara implisit (A tipe tempat Anda memesan) atau Pengurutan [A] yang lebih baik. Itu akan menjadi
list.sorted(Ordering[TheType].reverse)
sortBy seperti menggunakan Ordering.by, jadi Anda bisa melakukannya
list.sorted(Ordering.by(_.size).reverse)
Mungkin bukan yang terpendek untuk menulis (dibandingkan dengan minus) tetapi tujuannya jelas
Memperbarui
Baris terakhir tidak berfungsi. Untuk menerima
_
inOrdering.by(_.size)
, kompilator perlu mengetahui tipe mana yang kita pesan, sehingga ia dapat mengetik_
. Tampaknya itu akan menjadi jenis elemen daftar, tetapi tidak demikian, karena tanda tangan diurutkandef sorted[B >: A](ordering: Ordering[B])
. Pengurutan mungkin aktifA
, tetapi juga pada leluhur mana punA
(Anda mungkin menggunakanbyHashCode : Ordering[Any] = Ordering.by(_.hashCode)
). Dan memang, fakta bahwa daftar adalah kovarian memaksa tanda tangan ini. Bisa dilakukanlist.sorted(Ordering.by((_: TheType).size).reverse)
tapi ini jauh lebih tidak menyenangkan.
sumber
list.sortBy(x => (-x.size, x.forTiesUseThisField))
list.sorted(Ordering.by((_: TheType).size).reverse)
menganggapnyalist.sorted(Ordering.by[TheType, Int](_.size).reverse)
lebih jelas (tetapi lebih lama) untuk poin pandangan saya.list.sortBy(_.size)(Ordering[Int].reverse)
juga suka .list.sortBy(_.size)(Ordering[Int].reverse)
sumber
mungkin untuk mempersingkatnya sedikit:
def Desc[T : Ordering] = implicitly[Ordering[T]].reverse List("1","22","4444","333").sortBy( _.size )(Desc)
sumber
Mudah sekali (setidaknya dalam kasus
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)
sumber
Keduanya
sortWith
dansortBy
memiliki sintaks yang ringkas: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))
Saya menemukan yang
sortWith
lebih mudah dimengerti.sumber
sortBy
memiliki parameter implisitord
yang menyediakan pengurutandef sortBy [B] (f: (A) ⇒ B)(implicit ord: Ordering[B]): List[A]
jadi, kita bisa mendefinisikan
Ordering
objeknya sendiriscala> 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)
sumber
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)
sumber
Kemungkinan lain dalam kasus di mana Anda meneruskan fungsi yang mungkin tidak dapat Anda ubah secara langsung ke Arraybuffer melalui sortWith misalnya:
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
sumber
ini kode saya;)
val wordCounts = logData.flatMap(line => line.split(" ")) .map(word => (word, 1)) .reduceByKey((a, b) => a + b) wordCounts.sortBy(- _._2).collect()
sumber