2012-02-15 34 views
2

试图解析出的Request.QueryString返回一个地图[字符串,序列[字符串]请告诉我Scala的方式做到这一点

var route = "" 
var queryString = "?" 
for((k,v) <- request.queryString) { 
    if(k == "route"){ route = v.head } 
    else { 
    queryString += k +"="+ v.head +"&" 
    } 
} 
queryString = queryString.substring(0, queryString.length() -1); 

这工作得很好,但十分必要。我相信有一个更实用的方法来做到这一点。任何帮助?

回答

7

帮助就在这里!过度评论。

val RouteKey = "route" 

val route = request 
    .getOrElse(RouteKey, Nil) // will return the route, or empty list 
    .headOption    // either Some[head] or None 
    .getOrElse("")   // if None, empty string 

val queryString = (request - RouteKey)  // remove the route from the request 
    .map { case (k, v) =>     // map each key/value pair 
    k + "=" + v.headOption.getOrElse("") } // into key=value strings 
    .mkString("?", "&", "")     // make that list into a single string 

你会发现,我用同样的方式安全地获得从列表中head,处理空列表。如果您发现自己做了很多,那么您可以将该方法添加到Seq[String]

implicit def pimpedStringSeq(seq: Seq[String]) = new { 
    def headStr = seq.headOption.getOrElse("") 
} 

val RouteKey = "route" 

val route = request.getOrElse(RouteKey, Nil).headStr 

val queryString = (request - RouteKey).map { case (k, v) => k + "=" + v.headStr } 
    .mkString("?", "&", "") 
2

没有那么好,但你可以使用折叠。

import scalaz._ 
import Scalaz._ 

request.queryString.foldLeft(("?", "")) { case ((route, queryString), (k, v)) => 
    if(k == "route") 
    (v.head, queryString) 
    else 
    (route, queryString + k + "=" + v.head + "&") 
} :-> (_.init) 

即可爱的笑容运算符(:->)是用于转化的2元组,我们在折叠的端部获得的第二元件。它可以被读作如下:

t :-> f == (t._1, f(t._2)) 

您可以看到源here。从控制台

例子:

scala> val requestQueryString = Map("route" -> Seq("a"), "foo" -> Seq("b"), "bar" -> Seq("c")) 
requestQueryString: scala.collection.immutable.Map[java.lang.String,Seq[java.lang.String]] = Map(route -> List(a), foo - 
> List(b), bar -> List(c)) 

scala> var route = "" 
var queryString = "?" 
for((k,v) <- requestQueryString) { 
    if(k == "route"){ route = v.head } 
    else { 
    queryString += k +"="+ v.head +"&" 
    } 
} 
queryString = queryString.substring(0, queryString.length() -1); 
route: java.lang.String = a 
queryString: java.lang.String = ?foo=b&bar=c 
queryString: java.lang.String = ?foo=b&bar=c 

scala> requestQueryString.foldLeft(("?", "")) { case ((queryString, route), (k, v)) => 
    if(k == "route") 
    (queryString, v.head) 
    else 
    (queryString + k + "=" + v.head + "&", route) 
} 
res8: (java.lang.String, java.lang.String) = (?foo=b&bar=c&,a) 

scala> ((_: String).init) <-: res8 
res9: (String, java.lang.String) = (?foo=b&bar=c,a) 

scala> requestQueryString.foldLeft(("?", "")) { case ((route, queryString), (k, v)) => 
    if(k == "route") 
    (v.head, queryString) 
    else 
    (route, queryString + k + "=" + v.head + "&") 
} :-> (_.init) 
res10: (java.lang.String, String) = (a,foo=b&bar=c) 
+2

': - >'在斯卡拉的目的是什么? – 2012-02-15 05:16:11

+1

无论目的是什么,操作员都会让我微笑: - > – Landei 2012-02-15 09:36:12

+0

@ om-nom-nom,我扩大了我的答案。 – missingfaktor 2012-02-15 11:19:07

相关问题