1

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?

2
  • 5
    Whatever library you use to send the request, already has a way to set and encode the parameters. Don't reinvent the bicycle. Commented Jul 26, 2017 at 22:12
  • Don't convert to String unless for debug. See the other comment. Commented Jul 27, 2017 at 3:38

2 Answers 2

5

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
Sign up to request clarification or add additional context in comments.

1 Comment

for idiom, m.map { case (k, v) => s"${enc(k)}=${env(v)}" }.
0

.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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.