Scala-写出时嵌套循环的替代方法

时间:2018-07-30 18:05:07

标签: scala nested-loops

为了介绍我的情况,我正在尝试生成多个日志文件,每个小时一个,将有随机数量的时间戳(行)。在编写代码时,我决定根据小时(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
}

编辑:为澄清起见,这与标准的多文件写出有所不同,因为小时数需要与文件名匹配。

1 个答案:

答案 0 :(得分:2)

一个简单的解决方案是使用理解:

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")
}

它具有一遍又一遍地重新创建File处理程序的缺点,因此性能可能是一个问题,但是如果此代码仅用于一次创建一些测试数据,则不必担心。

一种替代方法是直接按小时数顺序(然后是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: _*)
})