Если бы я хотел перечислить итерации внутреннего цикла в 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
}
}
Я мог бы избавиться от var
, используя val currentPageNumber = Iterator.from(0)
, но это все еще означает, что мне действительно нужно объявить его вне цикла.
Есть ли уловка, которая не выставит 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
.