16 January 2013

Scala Object Update - Formatting the map results

Working on the same Scala Script I pretty much finished it tonight.

I got the output to finally adhere to what I wanted:
title,category
title,category
...

Initially I was getting the entire map.  like the output was map("something")
Then when I previously combined maps I got output like
Title
Category
Title
Category

which isn't what I wanted.

So I updated the code to create a new method called jsonOutput, like this:
import scala.util.parsing.json._

object Parser {
  def main(args:Array[String]){
    for (i <- 1 until 1000) {
      try {
        val json = JSON.parseFull(scala.io.Source.fromURL("http://us.battle.net/api/wow/quest/" + i).getLines().mkString("\n"))
        val jsonType = json.asInstanceOf[Option[Map[String, String]]]
        val jsonTitle = jsonType.map(_("title")).get  
        val jsonLoc = jsonType.map(_("category")).get
        def jsonOutput() = jsonTitle+","+jsonLoc+"\n"

        jsonOutput() foreach {
          print

        }
      }catch {
        case e: Exception =>
      }
    }
  }
}

The updates are in Red above.  The first thing I did was update the foreach to point to my new method (ditching my map ++ combining idea.)  I constructed the format in the method:
def jsonOutput() = jsonTitle+","+jsonLoc+"\n"

So I didn't need a println anymore, I opted for print.

This returned output like:
Some(Kanrethad's Quest),Some(Designer Island)

I really wanted the values in the Some... so I saw on StackOverflow they used .get method to retrieve the result... http://stackoverflow.com/questions/6385383/problem-with-outputting-map-values-in-scala

So I appended .get to the maps values I'm taking... and I got the anticipated output of:
Kanrethad's Quest,Designer Island
Sharptalon's Claw,Ashenvale
Riverpaw Gnoll Bounty,Elwynn Forest
Give Gerard a Drink,Elwynn Forest
...

Finally, I wanted to also output some values that were not Strings... but Integers... like the level of each quest.  To do that, I added a new map:
val jsonInt = json.asInstanceOf[Option[Map[String, Any]]]

Then, like before, called it with
val jsonLev = jsonInt.map(_("level")).get

And finally updated the jsonOutput method to be:
def jsonOutput() = jsonTitle+","+jsonTitle+","+jsonLev+"\n"

Which would give the output of:
Kanrethad's Quest,Designer Island,80.0
Sharptalon's Claw,Ashenvale,23.0
Riverpaw Gnoll Bounty,Elwynn Forest,10.0
Give Gerard a Drink,Elwynn Forest,1.0
Ursangous' Paw,Ashenvale,24.0
Shadumbra's Head,Ashenvale,24.0
Simmer Down Now,Ashenvale,25.0
Further Concerns,Elwynn Forest,10.0

Refactoring

I just realized I didn't need to have a duplicate MAP for an integer... so I reused the same map jsonType and just set it to String, Any.

The final code is:
import scala.util.parsing.json._

object Parser {
  def main(args:Array[String]){
    for (i <- 1 until 1000) {
      try {
        val json = JSON.parseFull(scala.io.Source.fromURL("http://us.battle.net/api/wow/quest/" + i).getLines().mkString("\n"))
        val jsonType = json.asInstanceOf[Option[Map[String, Any]]]
        val jsonTitle = jsonType.map(_("title")).get
        val jsonLoc = jsonType.map(_("category")).get
        val jsonLev = jsonType.map(_("level")).get
        def jsonOutput() = jsonTitle+","+jsonLoc+","+jsonLev+"\n"

        jsonOutput() foreach {
          print
        }
      }catch {
        case e: Exception =>
      }
    }
  }
}

No comments:

Post a Comment