Scala Iterator with Map and For

16,431

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 calling next again on the same iterator will fail with a NoSuchElementException. 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, the it iterator has advanced to its end.

Share:
16,431

Related videos on Youtube

ssanj
Author by

ssanj

Updated on February 03, 2020

Comments

  • ssanj
    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
    ssanj over 13 years
    You're right! I must have used the Iterator before I ran up the examples. Thanks! :)