Mi método favorito personal es hacer uso del orden implícito proporcionado para Tuples, ya que es claro, conciso y correcto:
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)
}
Esto funciona porque el compañero deOrdered
define una conversión implícita de Ordering[T]
a Ordered[T]
que está dentro del alcance de la implementación de cualquier clase Ordered
. La existencia de Ordering
s implícitos para Tuple
s permite una conversión deTupleN[...]
a Ordered[TupleN[...]]
siempre que Ordering[TN]
exista un implícito para todos los elementos T1, ..., TN
de la tupla, lo que siempre debería ser el caso porque no tiene sentido ordenar un tipo de datos con no Ordering
.
El orden implícito para Tuples es su opción para cualquier escenario de clasificación que involucre una clave de clasificación compuesta:
as.sortBy(a => (a.tag, a.load))
Como esta respuesta ha demostrado ser popular, me gustaría ampliarla, señalando que una solución similar a la siguiente podría, en algunas circunstancias, considerarse de nivel 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()
ordenará por nombre y es.sorted(Employee.orderingById)
ordenará por id. Esto tiene algunos beneficios:
- Las clases se definen en una única ubicación como artefactos de código visibles. Esto es útil si tiene ordenaciones complejas en muchos campos.
- La mayoría de las funciones de ordenación implementadas en la biblioteca scala operan utilizando instancias de
Ordering
, por lo que proporcionar una ordenación directamente elimina una conversión implícita en la mayoría de los casos.