scala - 如何在 Scala 中返回迭代器?

标签 scala iterator traits

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

最佳答案

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

  • How do I implement an iterator for an existing singly linked list?
  • why does this iterable implementation produce a stackoverflow?

  • 让我们假设你有一个类链表。要求是打印列表中的所有元素。
    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
    

    关于scala - 如何在 Scala 中返回迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2135462/

    相关文章:

    java - Apache Spark : how to call UDF over dataset in Java?

    rust - 特性未实现(实现特性的事物)

    python - 使用Python的itertools生成二维表索引

    c++ - 构造函数中的 noob Iterator 运行时错误

    c++ - 如何将 vector 中 pair 的第一个元素复制到另一个 vector ?

    rust - 获取给定 LHS 和 RHS 类型的 Add 实现的关联输出类型

    rust - `&str` 类型没有实现特征 [E0277]

    scala - SBT 项目刷新失败 [IntelliJ、Scala、SBT]

    java - scala 中的 protected 方法如何在 jvm 上工作

    scala currying/partials 构建函数过滤器列表