【发布时间】:2011-01-02 18:04:25
【问题描述】:
如果我想在 Scala 中枚举内部循环的迭代,我将如何以函数式风格处理它?
例如我将如何重写以下代码:
val documents = List("a" :: "b" :: Nil, "aa" :: "bb" :: Nil, "aaa" :: Nil)
var currentPageNumber = 0
documents.foreach { doc =>
for (page <- doc) {
currentPageNumber += 1
println("%d: %s".format(currentPageNumber.head, page)
// do something with page
}
}
我可以通过使用val currentPageNumber = Iterator.from(0) 摆脱var 但这仍然意味着我实际上需要在循环之外声明它。
是否有一个技巧不会将currentPageNumber 暴露给外部范围,并且——就像zipWithIndex 计数器一样——只存在于循环内部?
编辑:
我还找到了一个使用 scanLeft 的版本,但我认为它相当混乱。但也许有人可以以某种方式对其进行优化。
documents.scanLeft(0) { case (cnt, doc) =>
doc.zip(Iterator.from(cnt + 1).toIterable).map { case(page, cnt) =>
println("%d: %s".format(cnt, page))
cnt
} last
}
自己的解决方案(目前):
谢谢大家,我想我的想法是这样的
documents.flatMap{ doc =>
for (page <- doc) yield {
currentPageNumber: Int =>
"%d: %s".format(currentPageNumber, page)
}}.zipWithIndex.map (t => t._1(t._2 + 1)) map(println)
所以,诀窍是让currentPageNumber 犹豫不决,直到可以实际申请zipWithIndex。
【问题讨论】:
标签: scala functional-programming iterator count immutability