Мой личный любимый метод - использовать предоставленный неявный порядок для кортежей, поскольку он ясный, краткий и правильный:
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
.
Неявный порядок для кортежей - это ваш путь для любого сценария сортировки, включающего составной ключ сортировки:
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
, поэтому упорядочивание напрямую исключает неявное преобразование в большинстве случаев.