1

I am reading in a file, and appending line numbers to each file. Below is a List to facilitate this example:

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

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

My program is getting a bit of code-smell with using the ._1 & ._2 accessors. I created:

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

However, the only way I know how to make best use of this case class would be to use the following:

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

My question: why can't I do this?

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

I'm a bit weary of doing two passes on my file for the sake of using a case-class.

Thanks in advance

0

4 Answers 4

3

If you try that last line in the Scala REPL, you'll see why it doesn't work:

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

What this error means is that testList.zipWithIndex has type (String, Int), rather than type File. You're just missing one step here, which is mapping the list of line/index tuples to a list of File:

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

If you use Iterators you can avoid multiple passes (because they are lazy), e.g.

for ((line, lineNum) <- testList.iterator.zipWithIndex) yield File(line, lineNum)
1
  • worked, but had to add .toList at the end, was complaining about type mismatch. Thanks!
    – Tom K
    Commented Nov 3, 2016 at 4:17
1

I think all you need is to map the tuples into instances of your case class.

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))
1
  • 2
    testList.zipWithIndex.map(FileLine.tupled) is shorter
    – Łukasz
    Commented Nov 3, 2016 at 6:33
0

You can also simplify the anonymous functions { case (line, index) => File(line, index) } in the other answers to testList.zipWithIndex.map((File(_, _)).tupled).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.