2012-02-15 38 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

相關問題