Как настроить компонент CSV для отображения списка строк - PullRequest
0 голосов
/ 06 мая 2018

У меня есть CSV-файл, содержащий названия стран и годы, которые они выиграли на Евровидении:

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

и мой CSV (используя 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
  }
}

Теперь, поскольку страна и год не уникальны, у страны может быть несколько лет, когда они выиграли, поэтому, когда я получу Швецию:

CountryEurovision.countrEurovisionYearMap.get("Sweden")

У меня только опция res0: Option[String] = Some(2015) который я ожидаю, чтобы быть списком лет по стране ... даже если это страна всего один год, я получу список, а в случае Швеции я получу список 2012 и 2015 годов ...

Как мне изменить настройки для этого поведения?

1 Ответ

0 голосов
/ 06 мая 2018

Когда вы преобразуете linesIterator.map { row => row("Country") -> row("Year") } в Map с .toMap, для дублированных ключей будет сохраняться только последний, так как он будет заменять предыдущий.

Вы можете изменить это, имея уникальный элемент для каждого ключа (страны), сгруппировав значения (даты) для каждого ключа (до применения toMap) и изменив значение вашего Map на 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

, который производит:

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

Таким образом, .get("Sweden") вернет Some(List(1997, 2017)).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...