Tom K
Tom K

Reputation: 165

Scala and case classes

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

Upvotes: 1

Views: 88

Answers (4)

Alexey Romanov
Alexey Romanov

Reputation: 170859

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

Upvotes: 0

jwvh
jwvh

Reputation: 51271

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

Upvotes: 1

Jason Scott Lenderman
Jason Scott Lenderman

Reputation: 1918

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)

Upvotes: 2

Eric
Eric

Reputation: 1114

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

Upvotes: 3

Related Questions