Scala从指定格式文件提取每行首个元素生成目标数组
修正Scala代码以提取每行的第一个元素
首先,咱们先梳理下你原代码里的几个关键问题:
- 每次循环都把
array重新赋值为line.split("\\~"),这不仅覆盖了之前的结果,而且split("~")后得到的数组最后一个元素是空字符串(因为每行以~结尾),完全不是我们需要的内容。 - 尝试调用
array.split("\\*")是错误的:array是Array[String]类型,根本没有split方法,你应该处理的是每行去掉~后的字符串。 - 你没有把提取到的第一个元素(比如
AB、CD)添加到目标数组里,最后array根本不会是你想要的结果。 - 使用
var维护数组不符合Scala的函数式编程风格,我们可以用更优雅的方式实现。
方案1:修正命令式写法(贴近原代码结构)
如果你想保留类似原代码的循环结构,我们可以这样修改:
import scala.io.Source val bufferedSource = Source.fromFile("sample.txt") var resultArray = Array.empty[String] for (line <- bufferedSource.getLines()) { // 去掉行尾的~符号,得到干净的行内容 val cleanLine = line.stripSuffix("~") // 用*分割字符串,取第一个元素 val firstElement = cleanLine.split("\\*")(0) // 将元素添加到结果数组中 resultArray = resultArray :+ firstElement } // 务必关闭文件资源,避免泄漏 bufferedSource.close() // 验证结果 println(resultArray.mkString(", ")) // 输出: AB, CD, MN, AB
方案2:Scala函数式写法(推荐)
更符合Scala风格的做法是使用不可变集合和函数式操作,同时用Using自动管理文件资源(避免手动关闭的麻烦):
import scala.io.Source import scala.util.Using // Using会自动关闭文件资源,非常安全 val resultArray = Using(Source.fromFile("sample.txt")) { source => source.getLines() .map { line => // 先分割~取有效内容,再分割*取第一个元素 line.split("\\~").head.split("\\*").head } .toArray }.getOrElse(Array.empty[String]) // 如果文件读取失败,返回空数组 // 验证结果 println(resultArray.mkString(", ")) // 输出: AB, CD, MN, AB
代码说明:
getLines()获取文件的所有行,返回一个可迭代的Iterator[String]。map操作对每一行进行处理:先通过split("\\~").head获取去掉~后的内容,再通过split("\\*").head提取第一个元素。Using是Scala 2.13+提供的工具类,会自动处理资源的打开和关闭,避免资源泄漏。
内容的提问来源于stack exchange,提问作者Rjj
相关产品推荐
相关产品推荐

