2016-10-29 3 views
1

Click here to see the problem statement imageScalaのイテレータは、私はイテレータがそのように動作している理由を理解することは非常に懸命に試みた

を混乱されています。 1回実行した後であることを意味します。最後の要素を除くすべてのエレメントでイテレータバッファが上書きされます。

私は私のイテレータが空になってきて5回

result = lines.filter(_.nonEmpty).map(_.toInt) 

を与えた後、私の入力テキストファイル内の5つの要素を持っている場合、私は意味。

すべてのヘルプははるかに高く評価されて....事前

+0

@ victor-moroz私は今あなたがつかまえたことを実証していたのを見ています。答えは「はい、イテレータはあなたがそれらを悪用すると非常に混乱します。」 「私があなたを悪用すれば、簡単にデバッグできる方法で爆破してください」と言っても「失敗する」のような考えがあります。 –

答えて

0

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() 
} 

hdhdDefined変数はIterator.bufferedで使用されているとまったく同じバッファリングを行います。

+0

'.filter'で' hasNext'を呼び出すと、元のイテレータからいくつかの(すべての)要素が破壊されます。 REPLが 'hasNext'を呼び出すので、あなたがREPLでそれを行うと起こります。私はそれが実際にどのように動作するか説明した回答がありましたが、そのような説明は無関係です。ただしないでください。 –

+0

'Iterator.filter'コードはあなたのステートメントに直接矛盾します。 '.filter'を呼び出すだけで新しいオブジェクトが返され、バッファリングは' hasNext'と 'next'で起こります。 –

+0

コードスニペットが何を示しているかはっきりしていませんが、特定のイテレータの特定のメソッドが破壊的である場合とそうでない場合がありますが、実装の詳細なので、決してそれらに頼らざるを得ません。 –

関連する問題