滑动迭代器跳过元素?

时间:2015-09-25 09:54:39

标签: scala

我有一个定义如下的函数(为了参数而简化):

def sendRecords(records: Iterator[Map[String, String]]) = {
    records.sliding(10,10).foreach { case recordList => println(recordList) } 
} 

当我调用此函数时,我可以从println(以及知道预期的答案是什么)看到recordList确实是一批10,但不知何故来自'记录的某些项目&# 39;似乎被跳过了。在这种情况下,输出缺少第1,第12,第13,第24,第25 ......(即似乎有一些奇怪的正常性)。请注意,每个元素都是string->的映射。字符串(内容是保密的),但为了说明起见,输出的简化形式可以是

[1,2,3,4,5,6,7,8,9,10],[13,14,15,16,17,18,19,20,21,22],[....]

用于批处理案例和

[0,1,2,3,4,5,6,7,8,9], [10,11,12,13,14,15,16,17,18,19],[....]

用" toList.iterator" (见下文),这是预期的。在这些输出中,我已经用标识它们的索引替换了地图。

我完全不知道为什么会发生这种情况。请注意'记录'是我自己实现的迭代器(即hasNext和next) - 我怀疑它很重要。但实施起来相当复杂。我已添加了底部的主要部分。

有些迹象表明它是正确的

records.toList.iterator.sliding(10,10).foreach { case recordList => println(recordList) } 

工作正常,

records.foreach { println } 

也看起来像预期的那样(即它单独打印每个元素,列表完成)。

有人知道这里有什么 - 或者建议我可以尝试其他一些事情吗?任何帮助将非常感激。我正在使用scala 2.10.5。

(请注意,虽然toList.iterator hack有效,但这里不能接受,因为它会在内存中构建整个列表,这在生产中会太大了。)

谢谢! -Joris。

迭代器尚未完全整理,所以请原谅一些潜在的狡猾的代码(这可能导致了这个问题),但它的想法是迭代逗号分隔的文件(即"行"输入)具有相当复杂的标头定义(因此是状态方法)。我无法显示解码器,因为这是保密的,但我希望这应该足够了。也许我的hasNext / next存在缺陷。

class DecodingIterator(lines: Iterator[String]) extends Iterator[Map[String, String]] {
  val decoder = new StatefulDecoder()
  var cachedRecord = Map[String,String]()

  def hasNext: Boolean = {
    if (!lines.hasNext || decoder.inState(decoder.Finished()))
        false
    else {
      while(!decoder.inState(decoder.Data())) {
        decoder.processLine(lines.next)
      }
      decoder.processLine(lines.next)
      cachedRecord = decoder.lastRecord
      !decoder.inState(decoder.Finished())
    }
  }

  def next = cachedRecord
}

1 个答案:

答案 0 :(得分:0)

正如对问题的评论中所讨论的那样,问题在于迭代器的实现,迭代器在“hasNext'”上的表现并不明显。 (并且'滑动'导致连续多次调用它。)

修好后,一切正常。 感谢大家的帮助。