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

时间:2013-11-22 16:14:16

标签: 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)
    }
}

我的主要问题是:

  1. 为什么我需要将s解析为List的实例 - 它不应该已经是列表吗?
  2. 有没有办法用元组而不是列表来执行此操作?
  3. 是否有内置的方法来执行列表转换?

1 个答案:

答案 0 :(得分: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))

现在回答你的问题:

  

为什么我需要将s解析为List的实例 - 不应该已经解析了   是一个清单?

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

P.S。如果您想静默忽略与kv regexp不匹配的令牌,请使用map操作交换collect。当前实现将因MatchError

而死亡