2

我是 Scala 的新手,我的功能如下:

def selectSame(messages: BufferedIterator[Int]) = {
  val head = messages.head
  messages.takeWhile(_ == head)
}

这是从缓冲迭代器中仅选择与头部匹配的元素。我随后使用此代码:

val messageStream = List(1,1,1,2,2,3,3)
if (!messageStream.isEmpty) {
  var lastTimeStamp = messageStream.head.timestamp
  while (!messageStream.isEmpty) {
    val messages = selectSame(messageStream).toList
    println(messages)
}

在第一次执行时,我得到了预期的 (1,1,1),但是我只得到了 List(2),就像我丢失了一个元素一样......可能我对迭代器/列表做错了,但我在这里有点迷失了。

4

1 回答 1

5

ScaladocIteratortakeWhile

重用:调用此方法后,应丢弃调用它的迭代器,只使用返回的迭代器。使用旧迭代器是未定义的,可能会发生变化,并且也可能导致对新迭代器的更改。

所以这就是为什么。这基本上意味着你不能直接用Iteratorsand做你想做的事takeWhile。恕我直言,最简单的方法是快速编写自己的递归函数来做到这一点。

如果您想坚持使用Iterators,可以使用 上的sameElements方法在Iterator您要调用的位置生成副本dropWhile

更好:span反复使用:

def selectSame(messages: BufferedIterator[Int]) = {
  val head = messages.head
  messages.span(_ == head)
}

def iter(msgStream: BufferedIterator[Int]): Unit = if (!msgStream.isEmpty) {
  val (msgs, rest) = selectSame(msgStream)
  println(msgs.toList)
  iter(rest)
}

val messageStream = List(1,1,1,2,2,3,3)
if (!messageStream.isEmpty) {
  var lastTimeStamp = messageStream.head.timestamp
  iter(messageStream0
}
于 2013-05-03T14:51:25.423 回答