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