Scala Iterator with Map and For
Solution 1
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
Solution 2
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.
Related videos on Youtube
ssanj
Updated on February 03, 2020Comments
-
ssanj over 4 years
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?
-
ssanj over 13 yearsYou're right! I must have used the Iterator before I ran up the examples. Thanks! :)