我有一些迭代器
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
}
有没有功能性的方法呢?没有可变变量?
答案 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)
}