Scala:将Map [String,String]转换为String的惯用法

时间:2017-07-26 21:07:42

标签: scala

我有一张地图,其中包含一些HTTP参数,这些参数将发送到API。

val sortedParameters: SortedMap[String, String] = SortedMap(
        "oauth_nonce" -> nonce,
        "oauth_callback" -> callbackURL,
        "oauth_signature_method" -> signatureMethod,
        "oauth_consumer_key" -> consumerKey
      )

以上参数必须以key1=value1&key2=value2等格式进行URL编码和连接。 在Scala中实现这一目标的最佳惯用方法是什么?

2 个答案:

答案 0 :(得分:4)

与其他答案几乎相同,但包括编码。

scala> import scala.collection.immutable.SortedMap
import scala.collection.immutable.SortedMap

scala> val enc = (s: String) => java.net.URLEncoder.encode(s, "utf-8")
enc: String => String = $$Lambda$1060/160696258@6c796cc1

scala> val sortedMap = SortedMap("a" -> "b&&c means both b and c are true", "c" -> "d=1")
sortedMap: scala.collection.immutable.SortedMap[String,String] = Map(a -> b&&c means both b and c are true, c -> d=1)

scala> sortedMap.map(kv => s"${enc(kv._1)}=${enc(kv._2)}").mkString("&")
res2: String = a=b%26%26c+means+both+b+and+c+are+true&c=d%3D1

编辑: 以及评论中更惯用的解构:

sortedMap.map({ case (k, v) => s"${enc(k)}=${enc(v)}" }).mkString("&")
res2: String = a=b%26%26c+means+both+b+and+c+are+true&c=d%3D1

答案 1 :(得分:0)

每个元素上的

.map()创建k=v模式,然后使用TraversableOnce#foldLeft(z)(op)TraversableOnce#mkString(separator)

连接它们

例如,

scala> import scala.collection.SortedMap
import scala.collection.SortedMap

scala> val sortedParameters = SortedMap("a" -> 1, "b" -> 2, "c" -> 3)
sortedParameters: scala.collection.SortedMap[String,Int] = Map(a -> 1, b -> 2, c -> 3)

使用mkString

scala> sortedParameters.map(kv => kv._1 + "=" + kv._2).mkString("&")
res1: String = a=1&b=2&c=3

使用foldLeft

scala> sortedParameters.map(kv => kv._1 + "=" + kv._2)
                       .foldLeft(new String)((a, b) => { if(a.equals("")) b else a + "&" + b})
res2: String = a=1&b=2&c=3