SOM-snyttはここですが、起こっていた正確に何を説明していませんでした。
イテレータを変換するときは、変換の結果を保存し、そのイテレータのみを使用する必要があります。特に、イテレータのfilter
を呼び出すと内部的にバッファされ、元のイテレータでnext
が呼び出され、head
変数に保存されます。バッファされたものにnext
を呼び出すと、4が得られます。元のイテレータでnext
を呼び出すと、8つ目の要素が得られます。最初の要素はなくなります。あなたの代わりに書かれたい場合:
var result = lines.filter(_.nonEmpty).map(_.toInt)
var result = result.filter(_.nonEmpty).map(_.toInt)
var result = result.filter(_.nonEmpty).map(_.toInt)
あなたが望むようあなたが常に変換イテレータ上で動作しているので、あなたは、イテレータが空になることなく、多くの倍の最後の行を繰り返すことができます。
EDIT:バッファリングのコメントに対処する - ここIterator.filter
ためのコードがあります:
def filter(p: A => Boolean): Iterator[A] = new AbstractIterator[A] {
private var hd: A = _
private var hdDefined: Boolean = false
def hasNext: Boolean = hdDefined || {
do {
if (!self.hasNext) return false
hd = self.next()
} while (!p(hd))
hdDefined = true
true
}
def next() = if (hasNext) { hdDefined = false; hd } else empty.next()
}
hd
とhdDefined
変数はIterator.buffered
で使用されているとまったく同じバッファリングを行います。
出典
2016-10-29 21:57:26
Tim
@ victor-moroz私は今あなたがつかまえたことを実証していたのを見ています。答えは「はい、イテレータはあなたがそれらを悪用すると非常に混乱します。」 「私があなたを悪用すれば、簡単にデバッグできる方法で爆破してください」と言っても「失敗する」のような考えがあります。 –