2016-11-03 8 views
1

Я читаю в файле и добавляю номера строк в каждый файл. Ниже приведен список, чтобы облегчить этот пример:Scala и case classes

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

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

Моя программа получает немного кода-запаху с помощью ._1 & ._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) 

Я немного устал от выполнения двух проходов в моем файле ради использования класса case.

Заранее спасибо

ответ

2

Если вы используете Iterators вы можете избежать нескольких проходов (потому что они ленивы), например,

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

работал, но должен был добавить .toList в конце, жаловался на несоответствие типа. Благодаря! –

3

Если вы пытаетесь, что последняя строка в Scala РЕПЛ, вы поймете, почему он не работает:

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

Я думаю, что все, что вам нужно, это сопоставление кортежей в экземплярах вашего класса case.

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

'testList.zipWithIndex.map (FileLine.tupled)' короче –

0

Можно также упростить анонимные функции { case (line, index) => File(line, index) } в других ответах на testList.zipWithIndex.map((File(_, _)).tupled).