Скажем, у меня есть набор строк, который я хочу упорядочить по длине, но уникальным по нормальному Строка
уникальность. Я имею в виду, что я могу иметь более одной строки одинаковой длины в Set
, но они должны быть отсортированы по длине.
Я хочу выразить порядок следующим образом:
val orderByLength = Ordering[Int].on[String](_ length)
, что, на мой взгляд, выглядит очень красиво. Но если бы я бросил это в SortedSet, скажите так:
scala> val s = SortedSet("foo", "bar")(orderByLength)
s: scala.collection.immutable.SortedSet[java.lang.String] = TreeSet(bar)
Я получаю только «bar». Это связано с тем, что Упорядочивание
представляет собой общий порядок, и поэтому, когда compare
возвращает 0, элементы считаются идентичными.
Поэтому я думаю, что мне нужно сделать цепное упорядочение и сравнить Струны, если длины равны. Для этого я использовал шаблон «pimp my library» следующим образом:
trait ChainableOrderings {
class ChainableOrdering[T](val outer: Ordering[T]) {
def ifEqual(next: Ordering[T]): Ordering[T] = new Ordering[T] {
def compare(t1: T, t2: T) = {
val first = outer.compare(t1, t2)
if (first != 0) first else next.compare(t1, t2)
}
}
}
implicit def chainOrdering[T](o: Ordering[T]) = new ChainableOrdering[T](o)
}
Я могу использовать его примерно так:
val ordering = Ordering[Int].on[String](_ length) ifEqual Ordering[String]
Я подумал, что это действительно здорово, но потом я понял, что то, что я хотел сделать, на самом деле не для того, чтобы заказывать из-за естественного упорядочения строк я просто хотел упорядочить по размеру, а уникальность - по чему-то другому. Возможно ли это более элегантным способом?