在Scala中解析字符串到关联数组的更好方法?

Ert*_*ohl 0 scala

我目前有以下哪些有用,但我对Scala很新,我想知道是否有更好的方法.

val utmcsr = """.*utmcsr=(.*)""".r
val utmcmd = """.*utmcmd=(.*)""".r
val utmccn = """.*utmccn=(.*)""".r
val utmctr = """.*utmctr=(.*)""".r

val utmz = "14002953.138298057.2.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)"
utmz.split("""\|""").map {
        case utmcsr(s) => List("utmscr", s)
        case utmcmd(s) => List("utmcmd", s)
        case utmccn(s) => List("utmccn", s)
        case utmctr(s) => List("utmctr", s)
        case _ => ""
    }.foldLeft(Map[String,String]()) {
        (m, s) => 
            val key = s.asInstanceOf[List[String]].head
            val value = s.asInstanceOf[List[String]].tail.head
            m + (key -> value)
    }
}
Run Code Online (Sandbox Code Playgroud)

我的主要问题是:

  1. 为什么我需要解析s作为List的实例 - 它不应该已经是一个列表吗?
  2. 有没有办法用元组而不是列表来做到这一点?
  3. 是否有内置的方法来进行映射转换?

om-*_*nom 5

您的所有代码都可以通过以下方式编写:

val kv = """.*(utmcsr|utmcmd|utmccn|utmctr)=(.*)""".r
// assuming you don't want to do this generally, only utmcsr ... utmctr values are accepted
// otherwise there can be something like """.*([a-z]+)=(.*)""".r
val utmz = "14002953.138298057.2.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)"

utmz.split("""\|""").map {
    case kv(key, value) => key -> value
}.toMap
// Map(utmcsr -> google, utmccn -> (organic), utmcmd -> organic, utmctr -> (not%20provided))
Run Code Online (Sandbox Code Playgroud)

现在回答你的问题:

为什么我需要解析s作为List的实例 - 它不应该已经是一个列表吗?

由于默认情况 - 空字符串不是List.问题2和3在上面的代码段中展示.

PS如果你想静默忽略与kv regexp不匹配的令牌,请mapcollect操作交换.当前的实现将因MatchError而死亡