简体   繁体   English

Scala迭代器与地图和为

[英]Scala Iterator with Map and For

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]吗?

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

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. 迭代器上的foreach方法和遍历集合上的相同方法之间存在重要区别:当调用迭代器时, foreach将在完成时将迭代器留在其末尾。 So calling next again on the same iterator will fail with a NoSuchElementException . 因此,在同一个迭代器上再次调用next会因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). 相比之下,当在集合上调用时, foreach会保持集合中元素的数量不变(除非传递的函数添加以删除元素,但这是不鼓励的,因为它可能会导致令人惊讶的结果)。

... ...

As you can see, after the call to it.map , the it iterator has advanced to its end. 正如您所看到的,在调用it.mapit迭代器已经提前到了它的末尾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM