Méthode personnelle préférée consiste à utiliser l'ordre implicite fourni pour les tuples, car c'est clair, concis et correct :
case class A(tag: String, load: Int) extends Ordered[A] {
// Requis à partir de Scala 2.11 pour des raisons inconnues - le compagnon de Ordered
// devrait déjà être dans la portée implicite
import scala.math.Ordered.orderingToOrdered
def compare(that: A): Int = (this.tag, this.load) compare (that.tag, that.load)
}
Cela fonctionne parce que le compagnon de Ordered
définit une conversion implicite de Ordering[T]
à Ordered[T]
qui est en portée pour toute classe implémentant Ordered
. L'existence des Ordering
implicits pour les Tuple
permet une conversion de TupleN[...]
à Ordered[TupleN[...]]
à condition qu'un Ordering[TN]
implicite existe pour tous les éléments T1, ..., TN
du tuple, ce qui devrait toujours être le cas car il n'a pas de sens de trier sur un type de données sans Ordering
.
L'ordre implicite pour les Tuples est ce qu'il faut utiliser pour tout scénario de tri impliquant une clé de tri composite :
as.sortBy(a => (a.tag, a.load))
Comme cette réponse a été populaire, j'aimerais l'élargir, notant qu'une solution ressemblant à ce qui suit pourrait dans certaines circonstances être considérée comme de qualité entreprise™ :
case class Employee(id: Int, firstName: String, lastName: String)
object Employee {
// Notez que parce que `Ordering[A]` n'est pas contravariant, la déclaration
// doit être paramétrée par type dans le cas où vous voulez que l'ordre implicite
// s'applique aux sous-classes de `Employee`.
implicit def orderingByName[A <: Employee]: Ordering[A] =
Ordering.by(e => (e.lastName, e.firstName))
val orderingById: Ordering[Employee] = Ordering.by(e => e.id)
}
Étant donné es: SeqLike[Employee]
, es.sorted()
triera par nom, et es.sorted(Employee.orderingById)
triera par identifiant. Cela présente quelques avantages :
- Les tris sont définis en un seul endroit en tant qu'artefacts de code visibles. C'est utile si vous avez des tris complexes sur de nombreux champs.
- La plupart des fonctionnalités de tri implémentées dans la bibliothèque scala fonctionnent en utilisant des instances de
Ordering
, donc fournir un ordre directement élimine une conversion implicite dans la plupart des cas.