Reputation: 4232
I have a map that contains a few HTTP
parameters that will be sent to an API.
val sortedParameters: SortedMap[String, String] = SortedMap(
"oauth_nonce" -> nonce,
"oauth_callback" -> callbackURL,
"oauth_signature_method" -> signatureMethod,
"oauth_consumer_key" -> consumerKey
)
The above parameters have to be URL encoded and concatenated in the form key1=value1&key2=value2
etc.
What would be the best idiomatic way to achieve this in Scala?
Upvotes: 1
Views: 1567
Reputation: 2816
Pretty much the same as the other answer but including encoding.
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
EDIT: And a more idiomatic destructuring from a comment:
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
Upvotes: 5
Reputation: 31192
.map()
on each elem to create k=v
pattern then concat them using TraversableOnce#foldLeft(z)(op)
or TraversableOnce#mkString(separator)
example,
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)
using mkString
,
scala> sortedParameters.map(kv => kv._1 + "=" + kv._2).mkString("&")
res1: String = a=1&b=2&c=3
using 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
Upvotes: 0