如何分别读取文件的每一行,以便在每一行执行任务? -斯卡拉

时间:2019-02-05 21:04:59

标签: scala for-loop

我的目标是一次读取一个文件,并用“&”分隔该特定行,然后将该行中的所有数字相乘。

文件中的一行如下所示:

2&3&5&1

每行可以有任意数量的数字,并且可以像这样任意数量的行。

这是我尝试过的:

import scala.io.{BufferedSource, Source}

object Multiply {

  def processFile(fileName: String): Int = {

    val file = Source.fromFile(fileName)
    var product: Int = 1

    for (line <- file.getLines()) {
      val splits = line.split("&")
      for (x <- splits) {
        product *= x.toInt
      }
    }

    product
  }
}

这将返回整个文件的乘积。我需要该程序分别打印出每行的产品。我该如何实现?

2 个答案:

答案 0 :(得分:2)

我认为嵌套的for循环可能是您遇到的问题。两种方法都是从头开始使用for-yield方法和功能更强大的map开始的。 toList就是这样,它可以在REPL上打印。

scala> file
res25: String =
2&3&5&1
1&1&2&2
42&2&1&1
42&3&1&1

scala> for (line <- file.lines)
     | yield line.split("&").map(_.toInt).product
res26: Iterator[Int] = non-empty iterator

scala> res26.toList
res27: List[Int] = List(30, 4, 84, 126)

scala> file.lines.map(line => line.split("&").map(_.toInt).product).toList
res28: List[Int] = List(30, 4, 84, 126)

答案 1 :(得分:2)

这是一种修复方法:

import scala.io.Source

object Multiply {
  def main(args: Array[String]): Unit = {

    // assumes `fileName` is in the first arg
    val fileName = args(0)

    for (line <- Source.fromFile(fileName).getLines()) {
      println(line.split("&").map(_.toInt).product)
    }
  }
}

一些提示:

  • 不要引入不必要的瓶颈。带有签名def processFile(name: String): Int的函数几乎没有用,因为它既不能接受要在每一行上调用的回调,也不能返回整数序列,因此它不适合对每一行做
  • 使用productreduce代替可变的foldLeft累加器变量。例如

    line.split("&").map(_.toInt).foldLeft(1)(_ * _)
    

    将等同于您所做的事情,但是幸运的是,对于这种特殊情况,有一种较短的.product方法用于将序列中的所有数字相乘。

  • 您可以链接多个方法调用,而无需为每个中间结果引入变量。
  • 比较编辑历史记录:遵守命名约定,缩进代码。