Skala'da ters sıralama yapmanın en iyi yolu nedir? Aşağıdakilerin biraz yavaş olduğunu hayal ediyorum.
list.sortBy(_.size).reverse
SortBy'yi kullanmanın ancak ters sıralama elde etmenin uygun bir yolu var mı? Kullanmayı tercih etmem sortWith
.
Skala'da ters sıralama yapmanın en iyi yolu nedir? Aşağıdakilerin biraz yavaş olduğunu hayal ediyorum.
list.sortBy(_.size).reverse
SortBy'yi kullanmanın ancak ters sıralama elde etmenin uygun bir yolu var mı? Kullanmayı tercih etmem sortWith
.
Yanıtlar:
Bazı sayısal değerlere göre sıralıyorsanız, işareti değiştirmenin açık bir yolu olabilir.
list.sortBy(- _.size)
Daha genel olarak, sıralama, açık bir şekilde yapabileceğiniz örtük bir Sıralama ile sıralanan yöntemle yapılabilir ve Sıralama'nın bir tersi vardır (aşağıdaki liste tersi değil)
list.sorted(theOrdering.reverse)
Tersine çevirmek istediğiniz siparişin üstü kapalı sipariş ise, bunu [Sipariş [A]] (Sipariş ettiğiniz tip A) veya daha iyi Sipariş [A] ile elde edebilirsiniz. Olurdu
list.sorted(Ordering[TheType].reverse)
sortBy, Ordering.by'yi kullanmak gibidir, böylece
list.sorted(Ordering.by(_.size).reverse)
Belki yazmak için en kısa değil (eksi ile karşılaştırıldığında) ama niyet açıktır
Güncelleme
Son satır çalışmıyor. Kabul etmek _
in Ordering.by(_.size)
biz sipariş Hangi tipe üzerinde, derleyici ihtiyacı o yazabilirsiniz böylece, bilmek _
. Bu, listenin elemanının türü gibi görünebilir, ancak sıralanan imzanın olduğu gibi, bu böyle değildir
def sorted[B >: A](ordering: Ordering[B])
. Sıralama açık olabilir A
, aynı zamanda herhangi bir atasına da A
(kullanabilirsiniz byHashCode : Ordering[Any] = Ordering.by(_.hashCode)
). Ve aslında, listenin kovaryant olması bu imzayı zorlar. Biri yapabilir
list.sorted(Ordering.by((_: TheType).size).reverse)
ama bu çok daha az hoş.
list.sortBy(x => (-x.size, x.forTiesUseThisField))
list.sorted(Ordering.by((_: TheType).size).reverse)
düşünün list.sorted(Ordering.by[TheType, Int](_.size).reverse)
daha anlaşılır (ama daha uzun) veiw benim açımdan için.
list.sortBy(_.size)(Ordering[Int].reverse)
.
belki biraz daha kısaltmak için:
def Desc[T : Ordering] = implicitly[Ordering[T]].reverse
List("1","22","4444","333").sortBy( _.size )(Desc)
Kolay peasy (en azından durumunda 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)
sortBy
ord
sipariş sağlayan örtük parametresi vardır
def sortBy [B] (f: (A) ⇒ B)(implicit ord: Ordering[B]): List[A]
kendi Ordering
nesnesini tanımlayabiliriz
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)
Hem sortWith
ve sortBy
kompakt bir sözdizimi vardır:
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
Anlaması kolay olanı buluyorum .
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)
Bir Arraybuffer'da sortWith ile doğrudan değiştiremeyebileceğiniz bir işlevi geçirdiğiniz durumlarda başka bir olasılık:
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
bu benim kodum;)
val wordCounts = logData.flatMap(line => line.split(" "))
.map(word => (word, 1))
.reduceByKey((a, b) => a + b)
wordCounts.sortBy(- _._2).collect()