วิธีที่ฉันชอบคือการใช้คำสั่งโดยนัยที่ให้ไว้สำหรับทูเปิลเนื่องจากชัดเจนกระชับและถูกต้อง:
case class A(tag: String, load: Int) extends Ordered[A] {
// Required as of Scala 2.11 for reasons unknown - the companion to Ordered
// should already be in implicit scope
import scala.math.Ordered.orderingToOrdered
def compare(that: A): Int = (this.tag, this.load) compare (that.tag, that.load)
}
นี้ทำงานได้เพราะสหายOrdered
กำหนดแปลงนัยจากOrdering[T]
การที่อยู่ในขอบเขตการดำเนินการใดOrdered[T]
ๆ ในชั้นเรียน Ordered
การดำรงอยู่ของปริยายOrdering
สำหรับTuple
s ช่วยให้การแปลงจากTupleN[...]
การOrdered[TupleN[...]]
ให้โดยนัยOrdering[TN]
ที่มีอยู่สำหรับทุกองค์ประกอบT1, ..., TN
ของ tuple Ordering
ซึ่งควรจะเป็นกรณีนี้เพราะมันทำให้รู้สึกไม่ไปจัดเรียงบนชนิดของข้อมูลที่ไม่มี
การเรียงลำดับโดยปริยายสำหรับทูเปิลคือสิ่งที่คุณต้องทำสำหรับสถานการณ์การเรียงลำดับใด ๆ ที่เกี่ยวข้องกับคีย์การเรียงลำดับแบบผสม:
as.sortBy(a => (a.tag, a.load))
เนื่องจากคำตอบนี้ได้รับการพิสูจน์แล้วว่าเป็นที่นิยมฉันจึงขอขยายความโดยสังเกตว่าโซลูชันที่มีลักษณะดังต่อไปนี้อาจถือได้ว่าเป็นระดับองค์กร™:
case class Employee(id: Int, firstName: String, lastName: String)
object Employee {
// Note that because `Ordering[A]` is not contravariant, the declaration
// must be type-parametrized in the event that you want the implicit
// ordering to apply to subclasses of `Employee`.
implicit def orderingByName[A <: Employee]: Ordering[A] =
Ordering.by(e => (e.lastName, e.firstName))
val orderingById: Ordering[Employee] = Ordering.by(e => e.id)
}
ป.ร. ให้ไว้es: SeqLike[Employee]
, es.sorted()
จะเรียงตามชื่อและes.sorted(Employee.orderingById)
จะจัดเรียงตามรหัส สิ่งนี้มีประโยชน์บางประการ:
- ประเภทถูกกำหนดไว้ในตำแหน่งเดียวเป็นส่วนรหัสที่มองเห็นได้ สิ่งนี้มีประโยชน์หากคุณมีประเภทที่ซับซ้อนในหลายช่อง
- ฟังก์ชันการเรียงลำดับส่วนใหญ่ที่ใช้ในไลบรารีสกาล่าจะทำงานโดยใช้อินสแตนซ์
Ordering
ดังนั้นการจัดเรียงลำดับโดยตรงจะช่วยลดการแปลงโดยนัยในกรณีส่วนใหญ่