Scala:从IO读取文件并逐行匹配它构造一个案例类并将案例类添加到List

时间:2011-07-02 22:23:18

标签: scala

我一直在尝试在空闲时间学习Scala并学习以更实用的方式编写代码;无论如何我遇到了一个问题,试图写(我认为)将是一个简单的工具,从文件中读取格式化的名称数据,并创建包含案例类的数据的列表...但是这不起作用:

object NameDataUtil {

  /**
   * reads a data file containing formatted name data into a list containing case classes.
   *
   * @param fileName name of the file (with extension) to read the data from.
   * @return a list of case classes containing the data from the specified file.
   */
  def readInFile(fileName: String): List[NameDatum] = {

  val names: List[NameDatum] = Source.fromURL(getClass.getResource("/"+fileName)).getLines() foreach { line =>
    line.trim.split("\\s+")
    match {
      case Array(name,freq,cumFreq,rank) => NameDatum(name, freq.toDouble, cumFreq.toDouble, rank.toInt)
    }
  }

  names
  }
}

非常感谢任何帮助。谢谢!

2 个答案:

答案 0 :(得分:2)

foreach替换为map,您将获得Iterator[NameDatum]。在toList之后添加getLines()代替获得List[NameDatum],但如果您希望使用toStream并使用Stream[NameDatum],那么最好使用{{1}}太大了,无法满足记忆。

答案 1 :(得分:1)

我认为问题在于你正在使用具有返回类型单元的foreach;从以下内容中看到foreach的签名: http://www.scala-lang.org/api/current/index.html#scala.collection.Iterator

def foreach (f: (A) ⇒ Unit): Unit

诀窍是map,你可以看到方法签名(如上面的链接)

def map [B] (f: (A) ⇒ B): Iterator[B]

所以当你在每一行上执行匹配时,你会将类型A(行的类型(即字符串))映射到类型B,即NameDatum。

另外,你可能会觉得有趣的是你可以在匹配中使用正则表达式...这将是使用拆分的替代方法,请查看下面的技巧 http://ikaisays.com/2009/04/04/using-pattern-matching-with-regular-expressions-in-scala/