1

I have a csv file that holds country names and years they won on the eurovision:

country, year
Israel, 1998
Sweden, 2012
Sweden, 2015
United Kingdom, 1997

and my csv (using tototoshi):

object CountryEurovision {

  def countrEurovisionYearFile: File =  new File("conf/countryEurovision.csv")

  lazy val countrEurovisionYearMap: Map[String, String] = getConvertData

  private def getConvertData: Map[String, String] = {

    implicit object CodesFormat extends CSVFormat {
      val delimiter: Char = ','
      val quoteChar: Char = '"'
      val escapeChar: Char = '"'
      val lineTerminator: String = "\r\n"
      val quoting: Quoting = QUOTE_NONNUMERIC
      val treatEmptyLineAsNil: Boolean = false
    }

    val csvDataReader = CSVReader.open(countrEurovisionYearFile, "UTF-8")(CodesFormat)
    val linesIterator = csvDataReader.iteratorWithHeaders
    val convertedData = linesIterator.map { 
      row => row("Country") -> row("Year")
    }.toMap
    csvDataReader.close()
    convertedData
  }
}

now, since the country and year is not unique, cause a country can have several years when they won, so when I get Sweden:

CountryEurovision.countrEurovisionYearMap.get("Sweden")

I only get option res0: Option[String] = Some(2015) which I would expect to be the list of years per country... even if it's a country of just one year I will get a list, and in case of Sweden I will get list of 2012 and 2015...

How can I change my setup for that behavior?

1 Answer 1

1

When you transform linesIterator.map { row => row("Country") -> row("Year") } into a Map with .toMap, for duplicated keys only the last one will be kept as it will override the previous one.

You can change this by having a unique element per key (country) by grouping values (dates) per key (before applying toMap) and modifying the value of your Map to be a List:

linesIterator
  .map { row => row("Country") -> row("Year") } // List(("Sweden", 1997), ("France", 2008), ("Sweden", 2017))
  .groupBy(_._1) // Map(France -> List((France,2008)), Sweden -> List((Sweden,1997), (Sweden,2017)))
  .mapValues(_.map(_._2)) // Map(France -> List(2008), Sweden -> List(1997, 2017))
  .toMap

which produces:

Map(France -> List(2008), Sweden -> List(1997, 2017))

This way, .get("Sweden") will return Some(List(1997, 2017)).

Sign up to request clarification or add additional context in comments.

1 Comment

figured it out, i had to do .toList and then .groupBy

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.