Итератор Scala с картой и для
дано:
val list = List("one","two","three")
val it = list.toIterator
Я могу запустить:
list map ("_" +) -> List(_one, _two, _three)
for (i <- list) yield("_" + i) -> List(_one, _two, _three)
Если я запускаю то же самое на итераторе, я получаю:
it map ("_" + ) -> Iterator[java.lang.String] = empty iterator
for (i <- it) yield("_" + i) -> Iterator[java.lang.String] = empty iterator
не должен ли я получить еще один (непустой) итератор[String] после запуска map/for на нем?
2 ответов
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
может быть, вы использовали свой итератор?
scala> res26.foreach{println}
_one
_two
_three
scala> res26
res28: Iterator[java.lang.String] = empty iterator
поскольку итераторы имеют состояние и не сбрасываются, после его использования он пуст и не может быть использован снова.
вместо этого вы можете использовать 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
посмотреть итераторы.
существует важная разница между
foreach
метод на итераторах и тот же метод на проходимых коллекциях: при вызове итератораforeach
оставит итератор в конце, когда это будет сделано. Так зоветnext
снова на том же итераторе произойдет сбой сNoSuchElementException
. В отличие от этого, когда вызывается на сбор,foreach
оставляет количество элементов в коллекции без изменений (если только переданная функция добавляет к удаляет элементы, но это не рекомендуется, потому что это может привести к удивительным результатам).
...
как вы можете видеть, после вызова
it.map
, theit
итератор продвинулся до конца.