2017-12-08 7 views
1
val i = (1 to 8).toIterator 
val oneToThree = i.takeWhile(_ <= 3).toList 
// List(1, 2, 3) 

これまでのところとても良いです。 は、今私は、イテレータはまだ(3, 4, 5, 6, 7, 8)を含むようにしたいが、私は上で運ぶ場合:Scala Iterator.takeWhileが失敗した要素を破棄しています

val fourToSix = i.takeWhile(_ <= 6).toList 
// List(5, 6) 

エレメント3行方不明になっています。私はfourToSixList(4, 5, 6)であることが好ましいと思います。 takeWhileなどの操作を使用するにはどうすればよいですか?

答えて

5

takeWhile状態に関する資料その:

再利用:このメソッドを呼び出した後、1は、それが がコールされたイテレータを破棄し、返されただけでイテレータを使用する必要があります。 古いイテレータを使用すると、定義が変更される可能性があります。新しいイテレータにも同様に が変更される可能性があります。

iは、takeWhileを呼び出してから使用しないでください。


しかし、あなたは、あなたがspanメソッドを使用することができます欲しいものを達成するために:

scala> val i = (1 to 8).iterator 
i: Iterator[Int] = non-empty iterator 

scala> val (oneToThree, rest) = i.span(_ <= 3) 
oneToThree: Iterator[Int] = non-empty iterator 
rest: Iterator[Int] = unknown-if-empty iterator 

scala> oneToThree.toList 
res1: List[Int] = List(1, 2, 3) 

scala> val fourToSix = rest.takeWhile(_ <= 6) 
fourToSix: Iterator[Int] = non-empty iterator 

scala> fourToSix.toList 
res2: List[Int] = List(4, 5, 6) 
+0

だから私はIteratorを拡張するクラスを書いています。私は内部イテレータ(この例では 'i'に似ています)をオーバーライドした' next() 'で' i.takeWhile'を呼び出しています... 'i'を' var ' '私はspanを呼び出した後に' rest'に更新できますか? – Tom

+0

'var'への再割り当てがうまくいかないようだが、私はますます増え続けるイテレータのスタックを持っていて、' next'を呼び出すのが徐々に遅くなっている。 – Tom

+0

@Tom実際には、その場合、 'hasNext'と' next'を使って 'takeWhile'を自分で実装してみることをお勧めします。問題のコードがうまくいかない本当の理由は、イテレータから要素を取得した後、イテレータに戻すことができず、次の要素を「覗く」ためのインタフェースがないことです。したがって、オプションの現在の要素で内部変数を維持し、その述語に失敗した要素をその内部に配置する必要があります。詳細な情報がなくても詳細な回答は難しいので、このマニュアルの実装がうまくいかない場合は、より一般的な別の質問をすることを検討することもできます。 – Kolmar

関連する問題