2012-02-15 8 views
2

を行うにいただきましたScalaの道[文字列、配列[文字列]]地図を返す場合、Request.QueryStringを解析しようとすると、この

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

あまり良くはありませんが、折り畳みを使用することができます。キュートな笑顔オペレータ(:->)は、我々は倍の終わりに得る2組の第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) 

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

scalazの ': - ' 'の目的は何ですか? –

+1

目的が何であれ、オペレータは私を笑わせます: - > – Landei

+0

@ om-nom-nom、私は答えを広げました。 – missingfaktor