【问题标题】:How do you return an Iterator in Scala?如何在 Scala 中返回迭代器?
【发布时间】:2011-01-09 06:41:04
【问题描述】:

我必须做什么才能从方法/类返回迭代器?如何将这种特性添加到一个类中?

【问题讨论】:

    标签: scala iterator traits


    【解决方案1】:

    您可以扩展Iterator,这需要您实现nexthasNext 方法:

      class MyAnswer extends Iterator[Int] {
        def hasNext = true
        def next = 42
      }
    

    但是,如果您扩展Iterable,您将获得更大的灵活性,这需要您实现elements(或2.8 中的iterator):

      class MyAnswer extends Iterable[Int] {
        def iterator = new Iterator[Int] {
          def hasNext = true
          def next = 42
        }
      }
    

    一个常见的习惯似乎是将迭代器暴露给一些私有集合,像这样:

      class MyStooges extends Iterable[String] {
        private val stooges = List("Moe", "Larry", "Curly")
        def iterator = stooges.iterator
      }
    

    【讨论】:

    • 没有办法发送私人信息,但我想提出一个问题:您能否指出您提到的常用成语的用法?如果没有,它有什么用处?为什么不直接返回列表?这个成语不会效率低下吗? (另外:我已经看到 Iterable[A] “技巧”几次,它似乎是创建类似集合的最快方法之一,这种方法有什么“替代方案”吗?我问是因为 Iterator 给出信息很少,因此无法很好地优化方法,如果我知道我的伪 coll 返回有序或具有快速随机访问权限)
    【解决方案2】:

    对于方法,只需yield

    def odd(from: Int, to: Int): List[Int] = 
      for (i <- List.range(from, to) if i % 2 == 1) yield i
    

    【讨论】:

    • 正确,但是......代码示例实际上并没有回答问题。只需将“List”的两个实例都替换为“Iterator”,它就可以完美运行!
    【解决方案3】:

    这两个答案得到了下面帖子的帮助,感谢@Dima。

    假设您有一个类链表。并且要求是打印列表中的所有元素。

    trait LinkedList {
      def nodeValue: Int
      def tailList: LinkedList
    }
    
    class Node(val nodeValue: Int, val tailList: LinkedList) extends LinkedList
    
    object Nil extends LinkedList {
      def nodeValue = throw new IllegalAccessException("head of Nil")
      def tailList = throw new IllegalAccessException("tail of Nil")
    }
    
    val singleLinkedList = new Node(1,Nil)
    val chainedLinkedList = new Node(2,singleLinkedList)
    print(chainedLinkedList)
    A$A44$A$A44$Node@7b7a2c78res0: Unit = ()
    

    现在让我们为这个类实现迭代器。

    trait LinkedList extends Iterator[Int]{
      def nodeValue: Int
      def tailList: LinkedList
    }
    
    class Node(val nodeValue: Int, val tailList: LinkedList) extends LinkedList {
      var ptr: LinkedList = this
    
      //The following two are mandatory for extending Iterator
      override def hasNext: Boolean = ptr match { case Nil => false; case _=> true}
    
      override def next(): Int = {
        val result = ptr.nodeValue
        ptr = ptr.tailList
        result
      }
    }
    
    object Nil extends LinkedList {
      def nodeValue = throw new IllegalAccessException("head of Nil")
      def tailList = throw new IllegalAccessException("tail of Nil")
    
      //The following two are mandatory for extending Iterator
      override def hasNext: Boolean = false
      override def next(): Int = throw new IllegalAccessException("next of Nil")
    }
    
    val singleLinkedList = new Node(1,Nil)
    val chainedLinkedList = new Node(2,singleLinkedList)
    
    //Printing this first Time
    chainedLinkedList.foreach(println)
    //Prints 2 1
    
    //Printing second Time
    chainedLinkedList.foreach(println)
    //No output
    

    在迭代器实现中,一旦ptr到达末尾,它就不能前进了。可迭代的实现解决了这个问题。

    trait LinkedList extends Iterable[Int]{
      val nodeValue: Int
      val tailList: LinkedList
      override def toString(): String = this.mkString(" -> ")
    }
    
    class Node(val nodeValue: Int, val tailList: LinkedList) extends LinkedList {
    
      override def iterator: Iterator[Int] = Iterator
        .iterate(this: LinkedList)(_.tailList)
        .takeWhile(_ != Nil)
        .map(_.nodeValue)
    }
    
    object Nil extends LinkedList {
      lazy val nodeValue= throw new IllegalAccessException("head of Nil")
      lazy val tailList = throw new IllegalAccessException("tail of Nil")
    
      override def iterator: Iterator[Int] = Iterator.empty
    }
    
    val singleLinkedList = new Node(1,Nil)
    val chainedLinkedList = new Node(2,singleLinkedList)
    
    //Printing this first Time
    chainedLinkedList.foreach(println)
    Output 2 -> 1
    chainedLinkedList.foreach(println)
    Output 2 -> 1
    

    【讨论】:

      猜你喜欢
      • 2011-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-17
      相关资源
      最近更新 更多