2015-01-08 21 views
10

Ich extrahiere derzeit einige Metriken aus verschiedenen Datenquellen und speichert sie in einer Zuordnung des Typs Map[String,Any], wobei der Schlüssel dem Metriknamen entspricht und der Wert dem Metrikwert entspricht . Ich brauche das mehr oder weniger generisch, was bedeutet, dass Werttypen primitive Typen oder Listen primitiver Typen sein können.Zuordnung [Zeichenfolge, Beliebige] zu komprimieren JSON-Zeichenfolge mit JSON

Ich möchte diese Karte zu einer JSON-formatierten Zeichenfolge serialisieren und dafür verwende ich json4s Bibliothek. Die Sache ist, dass es nicht möglich scheint und ich sehe keine mögliche Lösung dafür. Ich würde so etwas wie die folgende erwarten aus dem Kasten heraus zu arbeiten :)

val myMap: Map[String,Any] = ... // extract metrics 
val json = myMap.reduceLeft(_ ~ _) // create JSON of metrics 

Navigation durch source code I json4s bietet implizite Konvertierungen, um primitive Typen JValue ‚s zu verwandeln gesehen habe und auch Traversable[A]/Map[String,A]/Option[A]-JValue zu konvertieren (unter der Einschränkung, eine implizite Umwandlung von A zu JValue verfügbar zu sein, was ich verstehe, bedeutet es eigentlich A ist ein primitiver Typ). Der Operator ~ bietet eine gute Möglichkeit, JObject 's aus JField' s zu konstruieren, was nur ein Typalias für (String, JValue) ist.

In diesem Fall ist Kartenwert Typ Any, so implizite Konvertierungen nicht stattfinden und damit der Compiler wirft der folgende Fehler:

    value ~ is not a member of (String, Any) 
[error]    val json = r.reduceLeft(_ ~ _) 

Gibt es eine Lösung für das, was ich erreichen will?

+0

Wenn ich Sie richtig verstehe und Sie möchten nur 'myMap' serialisieren, warum nicht' Serialization.write (myMap) 'direkt nennen? – edi

+1

@ user3567830 Ich möchte eine JSON-String-Repräsentation von 'myMap', das ist der Zweck der Verwendung einer JSON-Scala-Bibliothek wie' json4s' – jarandaf

+1

Ja, 'org.json4s.jackson.Serialization.write (myMap)' tut genau das. (Ich habe die jackson Version von json4s benutzt, aber das sollte auch für die native Version funktionieren). – edi

Antwort

26

Da Sie eigentlich nur nach der JSON-Zeichenfolgendarstellung myMap suchen, können Sie das Objekt Serialization direkt verwenden. Hier ist ein kleines Beispiel (wenn die native Version von json4s mit dem Import zu org.json4s.native.Serialization ändern):

EDIT: hinzugefügt formats impliziten

import org.json4s.jackson.Serialization 

implicit val formats = org.json4s.DefaultFormats 

val m: Map[String, Any] = Map(
    "name "-> "joe", 
    "children" -> List(
    Map("name" -> "Mary", "age" -> 5), 
    Map("name" -> "Mazy", "age" -> 3) 
    ) 
) 
// prints {"name ":"joe","children":[{"name":"Mary","age":5},{"name":"Mazy","age":3}]} 
println(Serialization.write(m)) 
+3

Nur zur weiteren Bezugnahme ist eine implizite 'Formats'-Instanz erforderlich, andernfalls wird der folgende Fehler angezeigt:' Keine org.json4s.Formats gefunden. Versuchen Sie, eine Instanz von org.json4s.Formats in den Bereich zu bringen, oder verwenden Sie org.json4s.DefaultFormats.'. Zum Beispiel, 'implizite val formats = org.json4s.DefaultFormats' löst das Problem. – jarandaf

+0

Danke, ich habe die Antwort aktualisiert. – edi

Verwandte Themen