0

I'm open to a different library if you can provide an easy template. I'd prefer a nested map output from my parsed JSON. Thanks!

The relevant code:

import scala.util.parsing.json.JSON
...
input = [Some file read in; see bottom for result]
val parsed = JSON.parseFull(input)
val parsedMap = (parsed.toList)(0)
println(parsedMap)
println(parsedMap.getClass())
println(parsedMap.keys)

The results, including error at bottom:

Map(interaction -> Map(author -> Map(name -> iBuyCell, avatar -> http://a0.twimg.com/profile_images/1751023331/SellingYourCell1_normal.png, username -> iBuyCell, id -> 4.62459933E8, link -> http://twitter.com/iBuyCell), source -> twitterfeed, id -> 1e17bc84c345a800e0742ed998fff162, link -> http://twitter.com/iBuyCell/statuses/186347162957918208, content -> Phone ban presents challenge for police: Chapel Hill became the only town in the state and nation last week to p... http://t.co/xVCQMDU7, created_at -> Sun, 01 Apr 2012 07:00:00 +0000, type -> twitter), links -> Map(created_at -> List(Sun, 01 Apr 2012 04:22:36 +0000), retweet_count -> List(3.0), title -> List(Phone ban presents challenge for police - Orange County - NewsObserver.com), url -> List(http://www.newsobserver.com/2012/04/01/1970433/police-challenged-by-cell-phone.html)), salience -> Map(content -> Map(sentiment -> -1.0)), language -> Map(tag -> en), raw_links -> List(http://bit.ly/HwmJa6), twitter -> Map(source -> twitterfeed, domains -> List(bit.ly), text -> Phone ban presents challenge for police: Chapel Hill became the only town in the state and nation last week to p... http://t.co/xVCQMDU7, links -> List(http://bit.ly/HwmJa6), id -> 186347162957918208, created_at -> Sun, 01 Apr 2012 07:00:00 +0000, user -> Map(utc_offset -> -14400.0, name -> iBuyCell, screen_name -> iBuyCell, location -> Text (Bez) Buy Kyts, url -> http://way.to/FreeFones, description -> Need Cash FAST? Text us 24Hrs For a Quick Quote! In The Mean Time, If You Need a New FREE Cell Phone, With Choice Of Carrier & Style, Click on Website Below!, id_str -> 462459933, listed_count -> 1.0, followers_count -> 178.0, id -> 4.62459933E8, created_at -> Thu, 12 Jan 2012 23:58:34 +0000, lang -> en, time_zone -> Atlantic Time (Canada), statuses_count -> 13069.0)))

class scala.collection.immutable.HashMap$HashTrieMap

error: value keys is not a member of Any println(parsedMap.keys)

If it helps, here's the original JSON in question:

{"interaction":{"author":{"avatar":"http://a0.twimg.com/profile_images/1751023331/SellingYourCell1_normal.png","id":462459933,"link":"http://twitter.com/iBuyCell","name":"iBuyCell","username":"iBuyCell"},"content":"Phone ban presents challenge for police: Chapel Hill became the only town in the state and nation last week to p... http://t.co/xVCQMDU7","created_at":"Sun, 01 Apr 2012 07:00:00 +0000","id":"1e17bc84c345a800e0742ed998fff162","link":"http://twitter.com/iBuyCell/statuses/186347162957918208","source":"twitterfeed","type":"twitter"},"language":{"tag":"en"},"links":{"created_at":["Sun, 01 Apr 2012 04:22:36 +0000"],"retweet_count":[3],"title":["Phone ban presents challenge for police - Orange County - NewsObserver.com"],"url":["http://www.newsobserver.com/2012/04/01/1970433/police-challenged-by-cell-phone.html"]},"raw_links":["http://bit.ly/HwmJa6"],"salience":{"content":{"sentiment":-1}},"twitter":{"created_at":"Sun, 01 Apr 2012 07:00:00 +0000","domains":["bit.ly"],"id":"186347162957918208","links":["http://bit.ly/HwmJa6"],"source":"twitterfeed</a>","text":"Phone ban presents challenge for police: Chapel Hill became the only town in the state and nation last week to p... http://t.co/xVCQMDU7","user":{"created_at":"Thu, 12 Jan 2012 23:58:34 +0000","description":"Need Cash FAST? Text us 24Hrs For a Quick Quote! In The Mean Time, If You Need a New FREE Cell Phone, With Choice Of Carrier & Style, Click on Website Below!","followers_count":178,"id":462459933,"id_str":"462459933","lang":"en","listed_count":1,"location":"Text (Bez) Buy Kyts","name":"iBuyCell","screen_name":"iBuyCell","statuses_count":13069,"time_zone":"Atlantic Time (Canada)","url":"http://way.to/FreeFones","utc_offset":-14400}}}

Elliot JJ
  • 543
  • 6
  • 19
  • Have you tried `val parsedMap = (parsed.toList)(0).asInstanceOf[collection.immutable.HashMap[_,_]]`? – om-nom-nom Jan 18 '13 at 00:31
  • I've heard nothing good about scala's native json parser. What version of scala are you using? See this answer for several alternatives. http://stackoverflow.com/questions/12591457/scala-2-10-json-serialization-and-deserialization – Falmarri Jan 18 '13 at 00:36

2 Answers2

0

The docs say that parseFull returns an Option[Any] that holds either an Array[Any] or a Map[String, Any]. If you are sure you are parsing a JSON object and not an array, one way to do it would be:

JSON.parseFull(input).get match {
  case map: Map[String, Any] => {
    // do anything you have to do with the map here, e.g.:
    println(map.keys)
  }
}
Martin Blech
  • 13,135
  • 6
  • 31
  • 35
0

I copied your sample JSON and used it to initialize a String which I then passed to scala.util.parsing.json.JSON.parseFull. The result is an Option[Any], as advertised. You then use toList on that Option[Any] (which is in fact a Some in this case) and get a one-element List[Any] (were it a None, you'd get an empty List). You then select the first (and only) element of that List, yielding an Any.

At this point, with an Any in hand (which could be anything, duh...) you have the ability to invoke only those methods defined on type Any. Naturally that does not include keys!

One way you can proceed through this is with pattern matching, as Martin Blech illustrates. This kind of a case clause effectively combines an isInstanceOf[Type] (type test) and an asInstanceOf[Type] (cast) giving you a value that statically bears the type Map[String, Any]. That that point, you use methods like keys or keySet (and all the others defined for Map).

Lastly note that you'll get an unchecked type warning for that case since the value in question is indistinguishable from all other Map types, due to the JVM's type erasure.

Randall Schulz
  • 26,420
  • 4
  • 61
  • 81