Skip to content

Instantly share code, notes, and snippets.

@zerosign
Last active August 29, 2015 14:27
Show Gist options
  • Save zerosign/c80d85b3cd8d4201ac2c to your computer and use it in GitHub Desktop.
Save zerosign/c80d85b3cd8d4201ac2c to your computer and use it in GitHub Desktop.
import java.util.StringTokenizer
import scala.collection.JavaConversions._
import scala.reflect.runtime.universe._
import scala.reflect._
/**
* Utility object for querying Map[String, Any] like object.
*
* @author: Yuri Setiantoko
*
*/
object JsonSelector {
val Pattern = "\\[(\\w+)\\]".r
/**
* Selector for Map[String, Any] type.
*
* It could query any instance of Map[String, Any] with this kind of DSL :
*
* data = { key : { key2 : 1 }, data: [1, 1] }
*
* - "key.key2" => Some(1)
* - "key.data.[1]" => Some(1)
* - "key" => Some({ key2 : 1 })
*
*/
def select[T](data: Map[String, Any], selector: String) : Option[T] = {
val iterator = new StringTokenizer(selector, ".")
var next: Option[Any] = Some(data)
iterator.foreach { key =>
next = key match {
case Pattern(kind) => {
next match {
case Some(value) => {
value match {
case data: List[Any] => Some(data(Integer.parseInt(kind)))
case _ => None
}
}
case _ => None
}
}
case _ => {
next match {
case Some(value) =>
value match {
case data: String => Some(data)
case data: Int => Some(data)
case data: Map[String, Any] => {
data.contains(key.toString) match {
case true => Some(data(key.toString))
case _ => None
}
}
case data: List[Any] => Some(data)
case data: Boolean => Some(data)
case data: Double => Some(data)
}
case _ => None
}
}
}
}
next match {
case Some(data) => Some(data.asInstanceOf[T])
case _ => None
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment