Как получить карту из строки CSV - PullRequest
6 голосов
/ 14 июля 2010

Я довольно новичок в Scala, но сейчас делаю упражнения.
У меня есть строка типа

<code>"A>Augsburg;B>Berlin"
. В конце я хочу карту

<code>val mymap = Map("A"->"Augsburg", "B"->"Berlin")

То, что я сделал, это:

<code>val st = locations.split(";").map(dynamicListExtract _)
с функцией
<code>private def dynamicListExtract(input: String)  = {
    if (input contains ">") {
      val split = input split ">"
      Some(split(0), split(1)) // return key , value
    } else {
      None 
    } 
  }
Теперь у меня есть
<code>Array[Option[(String, String)
Как мне элегантно преобразовать это в карту [String, String]

Кто-нибудь может помочь? Спасибо

Ответы [ 5 ]

11 голосов
/ 14 июля 2010

Просто измените свой map вызов на flatMap:

scala> sPairs.split(";").flatMap(dynamicListExtract _)
res1: Array[(java.lang.String, java.lang.String)] = Array((A,Augsburg), (B,Berlin))

scala> Map(sPairs.split(";").flatMap(dynamicListExtract _): _*)
res2: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map((A,Augsburg), (B,Berlin))

Для сравнения:

scala> Map("A" -> "Augsburg", "B" -> "Berlin")
res3: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map((A,Augsburg), (B,Berlin))
9 голосов
/ 14 июля 2010

В 2.8 вы можете сделать это:

val locations = "A>Augsburg;B>Berlin"
val result = locations.split(";").map(_ split ">") collect { case Array(k, v) => (k, v) } toMap

collect аналогичен map, но также фильтрует значения, которые не определены в частичной функции. toMap создаст Map из Traversable, если это Traversable[(K, V)].

3 голосов
/ 14 июля 2010

Также стоит посмотреть решение Рэндалла в форме для понимания, которая может быть более понятной или, по крайней мере, даст вам лучшее представление о том, что делает flatMap.

Map.empty ++ (for(possiblePair<-sPairs.split(";"); pair<-dynamicListExtract(possiblePair)) yield pair)
0 голосов
/ 16 июля 2010
val str= "A>Augsburg;B>Berlin"

Map(str.split(";").map(_ split ">").map(s => (s(0),s(1))):_*)

--or--

str.split(";").map(_ split ">").foldLeft(Map[String,String]())((m,s) => m + (s(0) -> s(1)))
0 голосов
/ 15 июля 2010

Простое решение (без обработки ошибок):

val str = "A>Aus;B>Ber"
var map = Map[String,String]()

str.split(";").map(_.split(">")).foreach(a=>map += a(0) -> a(1))

, но Бен Лингс лучше.

...