วิธีที่ดีที่สุดในการจัดเรียงผกผันในสกาล่าคืออะไร? ฉันคิดว่าสิ่งต่อไปนี้ค่อนข้างช้า
list.sortBy(_.size).reverse
มีวิธี conveinient ใช้ sortBy แต่รับเรียงกลับกัน? sortWith
ผมค่อนข้างจะไม่จำเป็นต้องใช้
วิธีที่ดีที่สุดในการจัดเรียงผกผันในสกาล่าคืออะไร? ฉันคิดว่าสิ่งต่อไปนี้ค่อนข้างช้า
list.sortBy(_.size).reverse
มีวิธี conveinient ใช้ sortBy แต่รับเรียงกลับกัน? sortWith
ผมค่อนข้างจะไม่จำเป็นต้องใช้
คำตอบ:
อาจมีวิธีที่ชัดเจนในการเปลี่ยนเครื่องหมายถ้าคุณเรียงตามค่าตัวเลขบางอย่าง
list.sortBy(- _.size)
โดยทั่วไปแล้วการเรียงลำดับอาจทำได้โดยวิธีการเรียงลำดับที่มีการสั่งซื้อโดยนัยซึ่งคุณอาจระบุไว้อย่างชัดเจนและการสั่งซื้อนั้นมีการย้อนกลับ (ไม่ใช่รายการที่กลับด้านล่าง) คุณสามารถทำได้
list.sorted(theOrdering.reverse)
หากการสั่งซื้อที่คุณต้องการย้อนกลับเป็นการสั่งซื้อโดยปริยายคุณสามารถรับได้โดยสั่ง [การสั่งซื้อ [A]] (ประเภทที่คุณสั่งซื้อ) หรือการสั่งซื้อที่ดีกว่า [A] นั่นจะเป็น
list.sorted(Ordering[TheType].reverse)
sortBy เป็นเหมือนการใช้ Ordering.by ดังนั้นคุณสามารถทำได้
list.sorted(Ordering.by(_.size).reverse)
อาจไม่ใช่การเขียนที่สั้นที่สุด (เทียบกับลบ) แต่เจตนาชัดเจน
ปรับปรุง
บรรทัดสุดท้ายไม่ทำงาน ที่จะยอมรับ_
ในความต้องการที่จะรู้ว่าคอมไพเลอร์ที่พิมพ์เรามีการสั่งซื้อเพื่อให้สามารถพิมพ์Ordering.by(_.size)
_
มันอาจจะดูเหมือนว่าจะเป็นชนิดขององค์ประกอบของรายการ
def sorted[B >: A](ordering: Ordering[B])
แต่ตอนนี้ไม่เป็นเช่นนั้นเป็นลายเซ็นของเรียงเป็น การสั่งซื้ออาจจะเปิดA
แต่ยังอยู่ในบรรพบุรุษของA
(คุณอาจใช้byHashCode : Ordering[Any] = Ordering.by(_.hashCode)
) และแน่นอนความจริงที่ว่ารายการนั้นแปรปรวนบังคับให้ลายเซ็นนี้ หนึ่งสามารถทำได้
list.sorted(Ordering.by((_: TheType).size).reverse)
แต่นี่เป็นสิ่งที่น่ายินดีน้อยกว่ามาก
list.sortBy(x => (-x.size, x.forTiesUseThisField))
list.sorted(Ordering.by((_: TheType).size).reverse)
คิดว่าlist.sorted(Ordering.by[TheType, Int](_.size).reverse)
มันชัดเจนกว่า (แต่นานกว่า) สำหรับประเด็น veiw ของฉัน
list.sortBy(_.size)(Ordering[Int].reverse)
ยัง
list.sortBy(_.size)(Ordering[Int].reverse)
อาจจะสั้นลงอีกเล็กน้อย:
def Desc[T : Ordering] = implicitly[Ordering[T]].reverse
List("1","22","4444","333").sortBy( _.size )(Desc)
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)
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)
ทั้งสอง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
ที่เข้าใจง่ายกว่า
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)
ความเป็นไปได้อีกอย่างในกรณีที่คุณส่งผ่านฟังก์ชั่นที่คุณอาจไม่สามารถแก้ไขโดยตรงไปยัง 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
นี่คือรหัสของฉัน;)
val wordCounts = logData.flatMap(line => line.split(" "))
.map(word => (word, 1))
.reduceByKey((a, b) => a + b)
wordCounts.sortBy(- _._2).collect()