Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flattening a Map to varargs String list in Scala

A Java event logging (analytics) library has a method that takes an event name and then varargs list of Strings like this:

Analytics.event("my event name", "key1", "value1", "key2", "value2" ...)

I've collected my event parameters in to a Map like

Map("key1" -> "value1", "key2" -> "value2" ...)

Now there must be a way to flatten the Map to list where keys and values alternate and then feed it to the event method. I've had several guesses, like transforming the Map to list a List of Tuples, but calling .flatten on that says

No implicit view available from (java.lang.String, java.lang.String) => scala.collection.TraversableOnce[B]

What am I missing here?

like image 835
vertti Avatar asked Nov 26 '11 19:11

vertti


3 Answers

You can use the : _* operator:

def event(name: String, values: String*) {/*...*/}

val params = Map("key1" -> "value1", "key2" -> "value2")
val paramsArr = params flatMap {case(k, v) => List(k, v)} toArray

event("name", paramsArr: _*)

Not sure whether this works with Java varargs as well (let us know!)

like image 102
Tomasz Nurkiewicz Avatar answered Nov 15 '22 05:11

Tomasz Nurkiewicz


You can use flatMap to map every key/value pair to a list with two elements and then concatenate these lists.

scala> Map("k1" -> "v1", "k2" -> "v2")
res0: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(k1 -> v1, k2 -> v2)

scala> res0.flatMap { case (k,v) => k::v::Nil }
res1: scala.collection.immutable.Iterable[java.lang.String] = List(k1, v1, k2, v2)

Once you have that, you can just pass the list to the event method:

Analytics.event("my event name", res1:_*)
like image 26
Kim Stebel Avatar answered Nov 15 '22 07:11

Kim Stebel


val m = Map ("key1" -> "value1", "key2" -> "value2", "k3"-> "v3")
val li = m.map ((e)=> List (e._1, e._2)).flatten.toSeq 
event ("name", li: _*)
like image 31
user unknown Avatar answered Nov 15 '22 05:11

user unknown