Given:
val list = List("one","two","three")
val it = list.toIterator
I can run:
list map ("_" +) -> List(_one, _two, _three)
for (i <- list) yield("_" + i) -> List(_one, _two, _three)
If I run the same on the iterator I get:
it map ("_" + ) -> Iterator[java.lang.String] = empty iterator
for (i <- it) yield("_" + i) -> Iterator[java.lang.String] = empty iterator
Shouldn't I get back another (non-empty) Iterator[String] after I run map/for on it?
See Iterators.
There's an important difference between the
foreach
method on iterators and the same method on traversable collections: When called to an iterator,foreach
will leave the iterator at its end when it is done. So callingnext
again on the same iterator will fail with aNoSuchElementException
. By contrast, when called on on a collection,foreach
leaves the number of elements in the collection unchanged (unless the passed function adds to removes elements, but this is discouraged, because it may lead to surprising results).
...
As you can see, after the call to
it.map
, theit
iterator has advanced to its end.
scala> def ints(n: Int): Stream[Int] = n #:: ints(n + 1)
ints: (n: Int)Stream[Int]
scala> val list = List("one","two","three")
list: List[java.lang.String] = List(one, two, three)
scala> val it = list.toIterator
it: Iterator[java.lang.String] = non-empty iterator
scala> it map ("_" + )
res24: Iterator[java.lang.String] = non-empty iterator
scala> it map ("_" + )
res25: Iterator[java.lang.String] = non-empty iterator
scala> for (i <- it) yield("_" + i)
res26: Iterator[java.lang.String] = non-empty iterator
Maybe you used your iterator?
scala> res26.foreach{println}
_one
_two
_three
scala> res26
res28: Iterator[java.lang.String] = empty iterator
Since iterators are stateful and not resettable, once you used it, it is empty and can't be used again.
Instead, you can use views:
scala> val v = list.view
v: java.lang.Object with scala.collection.SeqView[java.lang.String,List[java.lang.String]] = SeqView(one, two, three)
scala> v map ("_" + )
res29: scala.collection.SeqView[java.lang.String,Seq[_]] = SeqViewM(...)
scala> for (i <- v) yield("_" + i)
res30: scala.collection.SeqView[java.lang.String,Seq[_]] = SeqViewM(...)
scala> res29.foreach{println}
_one
_two
_three
scala> res29
res32: scala.collection.SeqView[java.lang.String,Seq[_]] = SeqViewM(...)
scala> res29.foreach{println}
_one
_two
_three
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With