Scala - 写出时替代嵌套 for 循环

Scala - Alternative to nested for loops while writing out

为了介绍我的情况,我正在尝试生成多个日志文件,每小时一个,其中包含随机数量的时间戳(行)。在编写代码时,我决定写出文件名并根据小时命名文件名 (log0 ... log23)。这样我就可以测试依赖于按小时分隔的日志的 Spark Streaming 作业。但是,除了嵌套 for 循环之外,想不出任何其他方法来做到这一点。

本着避免嵌套 for 循环和使代码更易于阅读的 Scala 精神,我正在寻找是否有一种方法可以重写以下具有相同功能的示例代码:

import scala.reflect.io.File

val hours = 24
val max_iterations = 100
val string_builder = scala.collection.mutable.StringBuilder.newBuilder
val rand = scala.util.Random

for (hour <- 0 until hours) {
    for (iter <- 1 to rand.nextInt(max_iterations)) {
        string_builder.append(s"{datetime=$hour:$minute:$second}\n")
    }
    File(s"log$hour.txt").createFile(false).writeAll(string_builder.toString)
    string_builder.clear
}

编辑:澄清一下,这不同于标准的多文件写出,因为时间需要与文件名匹配。

一个简单的解决方案是使用 for-comprehension:

for {
  hour <- 0 until hours
  iter <- 1 to rand.nextInt(max_iterations)
} yield {
  File(s"log$hour.txt").appendAll(s"{datetime=$hour:${iter%60}:00}\n")
}

它的缺点是一遍又一遍地重新创建文件处理程序,因此性能可能是个问题,但如果此代码仅用于创建一些测试数据一次,则这不应该是一个问题。

另一种方法是直接按小时顺序调用 foreach(然后是 iter 秒):

(0 until hours).foreach(hour => {
  val f = File(s"log$hour.txt")
  val lines = (1 to rand.nextInt(max_iterations)).map(iter => s"{datetime=$hour:${iter%60}:00}\n")
  f.writeAll(lines: _*)
})