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) を取得していますが、1 つの要素を失った場合のように、List(2) しか取得しません...おそらく、イテレータ/リストで間違っている可能性があります、しかし、私はここで少し迷っています。

4

1 に答える 1

5

Scaladoc は次のようにIterator述べていtakeWhileます。

再利用: このメソッドを呼び出した後、それが呼び出された反復子を破棄し、返された反復子のみを使用する必要があります。古い反復子の使用は定義されておらず、変更される可能性があり、新しい反復子も変更される可能性があります。

だから。Iteratorsこれは基本的に、 and でやり​​たいことを直接行うことができないことを意味しますtakeWhile。私見、最も簡単なのは、それを行うための独自の再帰関数をすばやく作成することです。

に固執したい場合は、 のメソッドをIterators使用して、を呼び出す場所に複製を生成できます。sameElementsIteratordropWhile

さらに良い: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 に答える