Scala SortedSet - отсортирован по одному Упорядочиванию и уникален по другому?

Скажем, у меня есть набор строк, который я хочу упорядочить по длине, но уникальным по нормальному Строка уникальность. Я имею в виду, что я могу иметь более одной строки одинаковой длины в 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]

Я подумал, что это действительно здорово, но потом я понял, что то, что я хотел сделать, на самом деле не для того, чтобы заказывать из-за естественного упорядочения строк я просто хотел упорядочить по размеру, а уникальность - по чему-то другому. Возможно ли это более элегантным способом?

9
задан Viktor Hedefalk 10 February 2011 в 01:03
поделиться