在Scala中对有序集的反转进行迭代?

时间:2015-06-09 15:46:11

标签: scala sortedset

我有一个可变的SortedSet,我可以通过执行for (item <- nameOfMySortedSet)来迭代它。但是我希望能够做同样的事情,但是在nameOfMySortedSet的反面。我似乎没有看到此数据类型的reverse()选项?还有另一种方法吗?

4 个答案:

答案 0 :(得分:3)

您可以尝试构建一个反向排序的新SortedSet:

scala> val mySet = collection.mutable.SortedSet("1", "2", "3")
mySet: scala.collection.mutable.SortedSet[String] = TreeSet(1, 2, 3)

scala> collection.mutable.SortedSet(mySet.toSeq:_*)(mySet.ordering.reverse)
res0: scala.collection.mutable.SortedSet[String] = TreeSet(3, 2, 1)

或者您可以将其转换为列表或seq并反向运行:

scala> mySet.toSeq.reverse
res1: Seq[String] = ArrayBuffer(3, 2, 1)

答案 1 :(得分:2)

解决方案,

val sSet = SortedSet(4,3,5)
sSet.foldLeft(List[Int]())((x,y)=>y::x)

如果您经常这样做,则可能必须以相反的顺序保存Set。使用其他Ordering

答案 2 :(得分:0)

以下作品,但我不想保证它有效:

  val s = collection.SortedSet(1,3,4)
  for (i <- s.to[List].reverse)
    println(i)

答案 3 :(得分:0)

大多数时候,我们只需要最后几个元素,这就是迭代器的用途。 另一种方法是不折叠所有元素或完全构造一个新的SortedSet实例。

我们可以有一个反向迭代器,该迭代器从上一次开始,每次next调用都以log(n)复杂度逐个选择每个元素。

以下是针对同一内容的优化实现。

object SortedSetExtras {

  implicit class ReverseIterator[A](val set: mutable.SortedSet[A]) extends AnyVal {

    def reverseIterator: Iterator[A] = new Iterator[A] {
      var upNext: Option[A] = None
      var upNextComputed: Boolean = false

      private def recompute(): Unit = {
        if (!upNextComputed) {
          upNext = upNext match {
            case Some(value) => set.until(value).lastOption
            case None => set.lastOption
          }
          upNextComputed = true
        }
      }

      override def hasNext: Boolean = if (upNextComputed) upNext.nonEmpty else {
        recompute()
        hasNext
      }

      override def next: A = {
        if (upNextComputed) {
          upNext.foreach(_ => upNextComputed = false)
          upNext.get
        } else {
          recompute()
          next()
        }
      }
    }
  }
}

实际用法-

import SortedSetExtras._

val ts = mutable.TreeSet[Int](1, 2, 3, 8, 9)

println(ts.reverseIterator.mkString(", ")) // 9, 8, 3, 2, 1

注意:以上实现不是线程安全的。