带有 Map 和 For 的 Scala 迭代器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4882876/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:46:58  来源:igfitidea点击:

Scala Iterator with Map and For

scalamapiteratorfor-loopscala-collections

提问by ssanj

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?

在我运行 map/for 之后,我不应该取回另一个(非空)Iterator[String] 吗?

回答by IttayD

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

回答by Eugene Yokota

See Iterators.

请参阅迭代器

There's an important difference between the foreachmethod on iterators and the same method on traversable collections: When called to an iterator, foreachwill leave the iterator at its end when it is done. So calling nextagain on the same iterator will fail with a NoSuchElementException. By contrast, when called on on a collection, foreachleaves 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).

foreach迭代器上的方法和可遍历集合上的相同方法之间有一个重要区别:当调用迭代器时,foreach将在完成后将迭代器留在其末尾。因此,next再次调用同一个迭代器将失败并显示NoSuchElementException. 相比之下,当在集合上调用时,集合foreach中元素的数量保持不变(除非传递的函数添加到删除元素,但不鼓励这样做,因为它可能会导致令人惊讶的结果)。

...

...

As you can see, after the call to it.map, the ititerator has advanced to its end.

如您所见,在调用 之后it.mapit迭代器前进到它的末尾。