メソッド/クラスから Iterator を返すにはどうすればよいですか? その特性をクラスにどのように追加しますか?
17298 次
3 に答える
33
Iteratorを拡張できます。これには、メソッドnext
とhasNext
メソッドを実装する必要があります。
class MyAnswer extends Iterator[Int] {
def hasNext = true
def next = 42
}
ただし、 Iterableを拡張すると、柔軟性が向上します。これには、実装elements
(またはiterator
2.8)が必要です。
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
}
于 2010-01-25T20:52:27.263 に答える
11
メソッドの場合は、単にyield :
def odd(from: Int, to: Int): List[Int] =
for (i <- List.range(from, to) if i % 2 == 1) yield i
于 2010-01-25T21:12:15.100 に答える
1
これらの 2 つの回答は、以下の投稿と @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
于 2017-07-03T16:46:29.160 に答える