如何在没有可变变量的情况下动态修改Iterator?

时间:2017-11-21 22:53:55

标签: scala iterator

我有一些迭代器

val i: Iterator[String] = //..

正在迭代非常大量的String s。因此无法将所有内容加载到内存中。我需要生成Iterator[String],它在源迭代器的每个元素之间插入分隔符(比如"separator")。实例

["1", "2", "3"] --> ["1", "separator", "2", "separator", "3"]
["1", "2"] --> ["1", "separator", "2"]
["1"] --> ["1"]
[] --> ["1"]

我找到了一个带有可变变量的解决方案:

class SeparatedIterator(i: Iterator[String]) extends Iterator[String] {
    private var pointToElement = false

    override def hasNext: Boolean =
      if (pointToElement && i.hasNext) true
      else i.hasNext

    override def next(): String =
      if(pointToElement && i.hasNext) {
        pointToElement = false
        "separator"
      }
      else if (i.hasNext) {
        pointToElement = true
        i.next()
      } else throw new NoSuchElementException
  }

有没有功能性的方法呢?没有可变变量?

1 个答案:

答案 0 :(得分:4)

您可以在输入迭代器上使用flatMap来用元素替换每个元素,然后使用分隔符。要避免最后的最后一个分隔符,可以添加一个if来检查迭代器中是否还有元素:

def separatedIterator(iter: Iterator[String]): Iterator[String] = {
    iter.flatMap { x =>
        if (iter.hasNext) Iterator(x, "separator")
        else Iterator(x)
    }
}

或者,根据Karl Bielefeldt的建议,您可以先放置分隔符,然后使用drop来摆脱它而不是if

def separatedIterator(iter: Iterator[String]): Iterator[String] = {
    iter.flatMap { x => Iterator("separator", x) }.drop(1)
}