Scala SortedSet - отсортировано по одному Порядку и уникально по другому? - PullRequest
9 голосов
/ 10 февраля 2011

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

Я получаю только «бар». Это потому, что Ordering представляет общее упорядочение, и поэтому, когда 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]

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

1 Ответ

18 голосов
/ 10 февраля 2011

Что я делаю в таких ситуациях:

val orderByLength = Ordering[(Int, String)].on[String](s => s.length -> s)

Другими словами, используйте кортеж, чтобы получить тай-брейк.

С другой стороны, я считаю глупым SortedSet считать элементы одинаковыми на основании их порядка . Я думаю, что это обсуждалось ранее, но я не отказался бы от возможности поиска в архивах списков рассылки и в scala trac для обсуждений / заявок по этому вопросу, и, возможно, пытался заставить SortedSet изменить его поведение.

...