Scala SortedSet - sorted by one Ordering and unique by something else?

情到浓时终转凉″ 提交于 2019-12-22 04:08:04

问题


Say I have a set of Strings that I want to be ordered by length but unique by the normal String uniqueness. What I mean is that I that I could have more than one String of same length in the Set, but that they should be sorted by length.

I want to express the ordering like this:

val orderByLength = Ordering[Int].on[String](_ length)

which I think looks really nice. But if I were to throw this into a SortedSet, say like this:

scala> val s = SortedSet("foo", "bar")(orderByLength)
s: scala.collection.immutable.SortedSet[java.lang.String] = TreeSet(bar)

I only get 'bar'. This is because the Ordering represents a total ordering and so when compare returns 0 the elements are considered identical.

Therefore I'm thinking I need to make a chained ordering and compare the Strings if the lengths are equal. To do this I used the "pimp my library"-pattern like this:

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)
}

That I can use like:

val ordering = Ordering[Int].on[String](_ length) ifEqual Ordering[String]

I thought it looked really great, but then I realized that what I wanted to do was not really to order by the natural ordering of Strings, I just wanted ordering by size, but uniqueness by something else. Is this possible in a more elegant way?


回答1:


What I do in such situations is this:

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

In other words, use a tuple to get a tie-breaker.

On the other hand, I think it's silly of SortedSet to consider elements the same based on their ordering. I think this has been discussed before, but I wouldn't discard the possibility of searching mailing lists archives and the scala trac for discussions/tickets on this, and maybe trying to get SortedSet to change its behavior.



来源:https://stackoverflow.com/questions/4952374/scala-sortedset-sorted-by-one-ordering-and-unique-by-something-else

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!