Ma méthode préférée personnelle est d'utiliser la commande implicite fournie pour les tuples, car elle est claire, concise et correcte:
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)
}
Cela fonctionne car le compagnon deOrdered
définit une conversion implicite de Ordering[T]
vers Ordered[T]
laquelle est dans la portée de toute implémentation de classe Ordered
. L'existence de Ordering
s implicite pour Tuple
s permet une conversion de à TupleN[...]
à Ordered[TupleN[...]]
condition qu'un implicite Ordering[TN]
existe pour tous les éléments T1, ..., TN
du tuple, ce qui devrait toujours être le cas car il n'a aucun sens de trier sur un type de données sans Ordering
.
L'ordre implicite pour les tuples est votre choix pour tout scénario de tri impliquant une clé de tri composite:
as.sortBy(a => (a.tag, a.load))
Comme cette réponse s'est avérée populaire, j'aimerais m'étendre là-dessus, en notant qu'une solution semblable à la suivante pourrait dans certaines circonstances être considérée comme de qualité entreprise ™:
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)
}
É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 dans un emplacement unique comme des artefacts de code visibles. Ceci 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 à l'aide d'instances de
Ordering
, donc fournir un ordre élimine directement une conversion implicite dans la plupart des cas.