app/utils/UnnaturalOrdering.scala (25 lines of code) (raw):

package utils /** Class to help ordering things in a mandated order, rather than the natural * ordering of a given type * @param order * The seq of objects in the order they should be returned in * @param aliensAtEnd * If true, the compare function will sort unknown items to the end, false * will sort them to the start * @tparam A * The type of the list of items to order */ class UnnaturalOrdering[A]( val order: List[A], val aliensAtEnd: Boolean = true, val oldOrdering: Ordering[A] ) extends Ordering[A] { val alienValue: Int = if (aliensAtEnd) order.size + 1 else -1 val orderMap: Map[A, Int] = order.zipWithIndex.map(e => e._1 -> e._2).toMap.withDefault(_ => alienValue) def compare(left: A, right: A): Int = { val leftIndex = orderMap(left) val rightIndex = orderMap(right) if (leftIndex == alienValue && rightIndex == alienValue) oldOrdering.compare(left, right) else leftIndex compare rightIndex } } object UnnaturalOrdering { def apply[A](order: List[A], aliensAtEnd: Boolean = true)(implicit oldOrdering: Ordering[A] ): UnnaturalOrdering[A] = { new UnnaturalOrdering[A](order, aliensAtEnd, oldOrdering) } }