从scala中的CSV文件中读取

时间:2016-02-09 16:03:13

标签: scala csv

我有一个文件,其中包含有关特定人口的不同数据信息。

文件格式示例:

1880,Mary,F,7065
1880,Anna,F,2604
1880,Emma,F,2003
1880,Elizabeth,F,1939

我们可以将这些数据解释为“在1880年,7065名女婴出生时被命名为Mary"

我有一个从文件中读取的函数

fromFile(name:String):List[List[String]]

fromFile返回列表列表:

列表(列表(" 1880"," Mary"," F"," 7065")

我无法弄清楚如何获取数据并将其解析为这样的函数,该函数采用嵌套列表和数字,并返回此年份的条目列表。  例如,如果' n'是1880年,然后返回列表将返回有关玛丽的所有信息。

 object readFile{
  val years = CSV.fromFile("my_file.csv") 

def yearIs(data: List[List[String]], n: Int): List[List[String]] = 
      ??
}

我试图弄清楚如何访问返回列表中的每个元素,并将其与给定的' int'进行比较,并返回所有数据。

2 个答案:

答案 0 :(得分:2)

我总是建议首先将输入数据转换为适当的结构并进行所有转换,然后执行错误报告,然后执行您想要执行的操作。

因此,一条记录的适当结构将是:

case class Record(year: Int, name: String, female: Boolean, count: Int)

让我们转换您的数据:

val data = CSV.fromFile("my_file.csv").map {
  case List(year, name, female, count) =>
    Record(year.toInt, name, female == "F", count.toInt)
}

如果你关心错误处理,你应该在这里捕获MatchError和NumberFormatException,或者尝试检测这些错误。

现在我们可以以类型安全和简洁的方式定义您的方法yearIs:

def yearIs(data: List[Record], year: Int) = data.filter(_.year == year)

您还可以直接创建从年份到回溯列表的地图:

val byYear: Map[Int, List[Record]] = data.record.groupBy(_.year)

答案 1 :(得分:1)

我认为获取“从n开始的年份列表”的最佳方法是使用nfilter与列表中的年份或第一个元素进行比较。

scala> def yearIs(data: List[List[String]], n: Int): List[List[String]] = {
     | data.filter(xs => xs.head.toInt > n)
     | }
yearIs: (data: List[List[String]], n: Int)List[List[String]]

scala> yearIs(data, 1880)
res6: List[List[String]] = List()

scala> yearIs(data, 1879)
res7: List[List[String]] = List(List(1880, Mary, F, 7065), List(1880, Anna, F, 2604), List(1880, Emma, F, 2003))