smms
smms

Reputation: 19

Scala populate a case class for each list item

I have a csv file of countries and a CountryData case class

Example data from file:

Denmark, Europe, 1.23, 7.89

Australia, Australia, 8.88, 9.99

Brazil, South America, 7.77,3.33

case class CountryData(country: String, region: String, population: Double, economy: Double)

I can read in the file and split, etc to get

(List(Denmark, Europe, 1.23, 7.89) (List(Australia, Australia, 8.88, 9.99) (List(Brazil, South America, 7.77,3.33)

How can I now populate a CountryData case class for each list item? I've tried:

for (line <- Source.getLines.drop(1)) {  
val splitInput = line.split(",", -1).map(_.trim).toList
val country = splitInput(0)
val region = splitInput(1)
val population = splitInput(2)
val economy = splitInput(3)

val dataList: List[CountryData]=List(CountryData(country,region,population,economy))

But that doesn't work because it's not reading the val, it sees it as a string 'country' or 'region'.

Upvotes: 0

Views: 741

Answers (2)

Alex Perez
Alex Perez

Reputation: 56

I would use scala case matching: i.e.

def doubleOrNone(str: Double): Option[Double] = {
   Try {
      Some(str.toDouble) //Not sure of exact name of method, should be quick to find
   } catch {
      case t: Throwable => None
  }
}    

def parseCountryLine(line: String): Vector[CountryData] = {
   lines.split(",").toVector match {
      case Vector(countryName, region, population, economy) => CountryData(countryName, region, doubleOrNone(population), doubleOrNone(economy))//I would suggest having them as options because you may not have data for all countries
      case s => println(s"Error parsing line:\n$s"); 
   }
}

Upvotes: 0

SergGr
SergGr

Reputation: 23788

It is not clear where exactly is your issue. Is it about Double vs String or about List being inside the loop. Still something like this will probably work

case class CountryData(country: String, region: String, population: Double, economy: Double)


object CountryDataMain extends App {
  val src = "\nDenmark, Europe, 1.23, 7.89\nAustralia, Australia, 8.88, 9.99\nBrazil, South America, 7.77,3.33"

  val list = Source.fromString(src).getLines.drop(1).map(line => {
    val splitInput = line.split(",", -1).map(_.trim).toList
    val country = splitInput(0)
    val region = splitInput(1)
    val population = splitInput(2)
    val economy = splitInput(3)

    CountryData(country, region, population.toDouble, economy.toDouble)
  }).toList

  println(list)
}

Upvotes: 0

Related Questions