Scala和案例类

时间:2016-11-03 03:56:23

标签: scala

我正在读取文件,并在每个文件中附加行号。下面是一个列表,以方便这个例子:

val testList: List[String] = List("Dont", "Do", "It"

val output: List[(String, Int)] = (testList.zipWithIndex)

使用._1&amp ;;我的程序有点代码味道。 ._2访问者。我创建了:

case class File(line: String, lineNum: Int)

但是,我知道如何充分利用此案例类的唯一方法是使用以下内容:

val fileOutput: List[File] = for{(line, lineNum) <- output} yield{File(line, lineNum)}

我的问题:为什么我不能这样做?

val output: List[File] = (testList.zipWithIndex)

我为了使用案例类而对我的文件进行两次传递感到有点厌倦。

提前致谢

4 个答案:

答案 0 :(得分:3)

如果你在Scala REPL中尝试最后一行,你就会明白为什么它不起作用:

scala> val output: List[File] = testList.zipWithIndex
<console>:13: error: type mismatch;
 found   : List[(String, Int)]
 required: List[File]
       val output: List[File] = testList.zipWithIndex

此错误意味着testList.zipWithIndex的类型为(String, Int),而不是File。您在此处缺少一步,即将行/索引元组列表映射到File列表:

scala> testList.zipWithIndex.map { case (line, index) => File(line, index) }
res0: List[File] = List(File(Dont,0), File(Do,1), File(It,2))

答案 1 :(得分:2)

如果你使用Iterators,你可以避免多次通过(因为它们是懒惰的),例如。

for ((line, lineNum) <- testList.iterator.zipWithIndex) yield File(line, lineNum)

答案 2 :(得分:1)

我认为您需要的只是将元组映射到案例类的实例中。

case class FileLine(line: String, lineNum: Int)

val testList: List[String] = List("Dont", "Do", "It")
val contents = testList.zipWithIndex.map{case (t,n) => FileLine(t,n)}
// contents: List[FileLine] = List(FileLine(Dont,0), FileLine(Do,1), FileLine(It,2))

答案 3 :(得分:0)

您还可以在{ case (line, index) => File(line, index) }的其他答案中简化匿名函数testList.zipWithIndex.map((File(_, _)).tupled)