开发者

Scala: Read file from IO and line by line match it construct a case class and add the case class to a List

开发者 https://www.devze.com 2023-03-17 02:42 出处:网络
I have been trying to learn Scala in my free time and learn to write code in a more functional manner; anyways I have hit a problem trying to write (what I thought) would be a simple tool for reading

I have been trying to learn Scala in my free time and learn to write code in a more functional manner; anyways I have hit a problem trying to write (what I thought) would be a simple tool for reading formatted name data out of a file and creating a List of that data containing case classes... this does not work however:

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

Any help is greatly appreciated. Thanks!


Replace foreach with map and you'll get an Iterator[NameDatum]. Add a toList after getLines() to get a List[NameDatum] instead, though it's probably better to use toStream and work with a Stream[NameDatum] instead, if you expect the file to be too big to fit all in memory.


i think the problem is that you're using foreach, which has a return-type of unit; see the signature of foreach from the following: http://www.scala-lang.org/api/current/index.html#scala.collection.Iterator

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

what would do the trick is map, you can see the method signature (as in the above link) is

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

so when you perform your match on each line, you will map the type A, which is the type of line (i.e., String) to the type B, which is your NameDatum.

also, something you might find interesting is that you can use a regex in a match... this would be an alternative to using the split, check out the technique at the following http://ikaisays.com/2009/04/04/using-pattern-matching-with-regular-expressions-in-scala/

0

精彩评论

暂无评论...
验证码 换一张
取 消