Я не уверен на 100%, какие методы, по вашему мнению, должны иметь collator
.
Но у вас будет больше гибкости, если вы определите порядок в классе дел:
val o = new Ordering[Name]{
def compare(a: Name, b: Name) =
3*math.signum(collator.compare(a.last,b.last)) +
math.signum(collator.compare(a.first,b.first))
}
names.sorted(o)
но вы также можете предоставить неявное преобразование из упорядочения строк в упорядочение имен:
def ostring2oname(os: Ordering[String]) = new Ordering[Name] {
def compare(a: Name, b: Name) =
3*math.signum(os.compare(a.last,b.last)) + math.signum(os.compare(a.first,b.first))
}
, а затем вы можете использовать любой упорядочивание строк для сортировки имен:
def oo = new Ordering[String] {
def compare(x: String, y: String) = x.length compare y.length
}
val morenames = List("rat","fish","octopus")
scala> morenames.sorted(oo)
res1: List[java.lang.String] = List(rat, fish, octopus)
Редактировать: Удобный трюк, если он не был очевидным, заключается в том, что если вы хотите упорядочить по N вещей, и вы уже используете сравнение, вы можете просто умножить каждую вещь на 3 ^ k (с первым кумножьте порядок на наибольшую степень 3) и добавьте
Если ваши сравнения занимают много времени, вы можете легко добавить каскадное сравнение:
class CascadeCompare(i: Int) {
def tiebreak(j: => Int) = if (i!=0) i else j
}
implicit def break_ties(i: Int) = new CascadeCompare(i)
, а затем
def ostring2oname(os: Ordering[String]) = new Ordering[Name] {
def compare(a: Name, b: Name) =
os.compare(a.last,b.last) tiebreak os.compare(a.first,b.first)
}
(просто осторожно вложите их x tiebreak ( y tiebreak ( z tiebreak w ) ) )
, чтобы не выполнять неявное преобразование несколько раз подряд).
(Если вам действительно нужно быстрое сравнениезатем вы должны выписать все это вручную или упаковать заказы в массив и использоватьпока цикл.Я предполагаю, что вы не так отчаянно нуждаетесь в производительности.)