带有 Map 和 For 的 Scala 迭代器

发布于 2024-10-15 23:01:52 字数 516 浏览 1 评论 0原文

给定:

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若水般的淡然安静女子 2024-10-22 23:01:52
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

由于迭代器是有状态的且不可重置,因此一旦使用它,它就是空的并且不能再次使用。

相反,您可以使用视图:

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
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
千柳 2024-10-22 23:01:52

请参阅迭代器

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

...

如您所见,在调用 it.map 后,it 迭代器已前进到末尾。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文