Мій особистий улюблений метод - використовувати надане неявне замовлення для Tuples, як це зрозуміло, стисло та правильно:
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
s для Tuple
s дає змогу перетворитись TupleN[...]
на Ordered[TupleN[...]]
умовне, що Ordering[TN]
існує неявне для всіх елементівT1, ..., TN
кортежу, що завжди має бути так, оскільки немає сенсу сортувати за типом даних без Ordering
.
Неявне впорядкування для Tuples - це перехід до будь-якого сценарію сортування, що включає складений ключ сортування:
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)
сортуватимуть за ідентифікатором. Це має кілька переваг:
- Сорти визначаються в одному місці як видимі артефакти коду. Це корисно, якщо у вас є складні сорти в багатьох полях.
- Більшість функцій сортування, реалізованих у бібліотеці scala, функціонують із застосуванням екземплярів
Ordering
, тому надання замовлення безпосередньо виключає неявне перетворення у більшості випадків.