Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala SortedSet-按一种顺序排序,并按其他顺序唯一?_Scala_Scala Collections - Fatal编程技术网

Scala SortedSet-按一种顺序排序,并按其他顺序唯一?

Scala SortedSet-按一种顺序排序,并按其他顺序唯一?,scala,scala-collections,Scala,Scala Collections,假设我有一组字符串,我想按长度排序,但按正常的字符串唯一性排序。我的意思是,我可以在集合中有多个长度相同的字符串,但它们应该按长度排序 我想这样表达订购: val orderByLength = Ordering[Int].on[String](_ length) scala> val s = SortedSet("foo", "bar")(orderByLength) s: scala.collection.immutable.SortedSet[java.lang.String] =

假设我有一组字符串,我想按长度排序,但按正常的
字符串
唯一性排序。我的意思是,我可以在
集合
中有多个长度相同的字符串,但它们应该按长度排序

我想这样表达订购:

val orderByLength = Ordering[Int].on[String](_ length)
scala> val s = SortedSet("foo", "bar")(orderByLength)
s: scala.collection.immutable.SortedSet[java.lang.String] = TreeSet(bar)
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 orderByLength = Ordering[Int].on[String](_ length)
scala> val s = SortedSet("foo", "bar")(orderByLength)
s: scala.collection.immutable.SortedSet[java.lang.String] = TreeSet(bar)
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)
}
我只得到“酒吧”。这是因为
排序
表示总排序,因此当
比较
返回0时,元素被认为是相同的

因此,我认为我需要进行链式排序,如果长度相等,则比较字符串。为此,我使用了“皮条客我的图书馆”模式,如下所示:

val orderByLength = Ordering[Int].on[String](_ length)
scala> val s = SortedSet("foo", "bar")(orderByLength)
s: scala.collection.immutable.SortedSet[java.lang.String] = TreeSet(bar)
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]

我觉得它看起来真的很棒,但后来我意识到我想做的不是按照字符串的自然顺序排序,我只是想按照大小排序,而是通过其他东西来排序。这可能是一种更优雅的方式吗?

我在这种情况下的做法是:

val orderByLength = Ordering[(Int, String)].on[String](s => s.length -> s)
换句话说,使用一个元组获得一个平局破坏者


另一方面,我认为<>代码> SoReSET 是基于它们的顺序考虑元素是愚蠢的。我想这之前已经讨论过了,但我不会放弃搜索邮件列表存档和scala trac以获取讨论/票证的可能性,也可能尝试获取

SortedSet
以更改其行为。

一个集合只包含不同的对象。排序集具有总排序。特别是,
S包含a
,而
S包含b
意味着
aeexcellent!这比我的版本要简洁得多。@rex它可能对预订购集()有用。对于所提供的
排序
使用一棵红黑树,其中包含
哈希集
的叶子,表示类型的自然排序/等价性。至少我的直觉是,提供的
排序
只用于排序,不用于寻找等价性,我不知道为什么。@hedefalk-事实上,我应该说“某种预排序”,因为即使是偏序也具有等价性。然而,单是预排序就太弱了,因为它承认元素可能是不可比较的。相反,在本例中,我们似乎希望定义每对元素的顺序关系,但顺序的等价类是完全正确的(
aInteresting.
java.util.TreeSet
,如果您使用字符串长度的比较器构造它,其工作方式与Scala
SortedSet
(它只保留一个给定长度的元素。)
Comparator
文档解释了原因:。不过我必须同意Daniel的观点,直觉上你会认为集合成员资格与排序是分开的。