Meu método favorito é fazer uso da ordenação implícita fornecida para tuplas, pois é claro, conciso e correto:
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)
}
Isso funciona porque o companheiro paraOrdered
define uma conversão implícita de Ordering[T]
para Ordered[T]
que está no escopo de qualquer implementação de classe Ordered
. A existência de Ordering
s implícitos para Tuple
s permite uma conversão de TupleN[...]
em, Ordered[TupleN[...]]
desde que Ordering[TN]
exista um implícito para todos os elementos T1, ..., TN
da tupla, o que sempre deve ser o caso, pois não faz sentido classificar por um tipo de dados com no Ordering
.
A ordenação implícita para Tuplas é a sua escolha para qualquer cenário de classificação que envolva uma chave de classificação composta:
as.sortBy(a => (a.tag, a.load))
Como esta resposta se provou popular, gostaria de expandi-la, observando que uma solução semelhante à seguinte poderia, em algumas circunstâncias, ser considerada de nível empresarial ™:
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)
}
Dado es: SeqLike[Employee]
, es.sorted()
irá classificar por nome e es.sorted(Employee.orderingById)
irá classificar por id. Isso tem alguns benefícios:
- As classificações são definidas em um único local como artefatos de código visíveis. Isso é útil se você tiver classificações complexas em muitos campos.
- A maioria das funcionalidades de classificação implementadas na biblioteca scala opera usando instâncias de
Ordering
, portanto, fornecer uma classificação elimina diretamente uma conversão implícita na maioria dos casos.