嘿伙计们我正在编写一个Scala函数,它最终会返回两个地图的三角形,我会递归地执行它,因为我不知道传入的地图会是什么样子。地图是转换的JSON对象。目前我正在编写一个函数,该函数使地图解析地图并返回相同的地图,它最终将接受两个地图并返回增量。当我到达阵列/列表时,我遇到了麻烦,不知道如何处理它们。任何指针都会受到赞赏。
编辑:好的,我得到了这个递归算法。我在for循环中返回,打破了循环,呃。
以下是我现在遇到的问题:
JSON In:
{"name":"Watership Down","location":{"lat":51.235685,"long":-1.309197},"residents":[{"name":"Fiver","age":4,"role":""},{"name":"Bigwig","age":6,"role":"Owsla"}]}
Json Out:
{"location":{"lat":51.235685,"long":-1.309197},"name":"Watership Down","residents":[{"role":"","age":4,"name":"Fiver"},{"role":"Owsla","age":6,"name":"Bigwig"}]}
编辑:一切正常。我在CompareMaps中使用scala.collection.mutable,将其变为不可变的并且它不会使订单混乱。 (在此处发现此问题:stackoverflow post)现在可以使用了!
守则:
import play.api.libs.json.{JsNull,Json,JsString,JsValue}
import play.api.libs.json._
import com.fasterxml.jackson.databind.{DeserializationFeature, ObjectMapper}
import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization
import scala.util.matching.Regex
import scala.collection.mutable.ListBuffer
object JsonCompare {
def main(args: Array[String]): Unit = {
val jsonT: JsValue = JsObject(Seq(
"name" -> JsString("andrew"),
"race" -> JsString("white"),
"characteristics" -> JsObject(Seq(
"body"-> JsString("avg"),
"height" -> JsString("tall"),
"head"-> JsObject(Seq(
"eyes" -> JsString("blue"),
"hair" -> JsString("brown")
))
))
))
val jsonZ: JsValue = JsObject(Seq(
"name" -> JsString("Watership Down"),
"location" -> JsObject(Seq("lat" -> JsNumber(51.235685), "long" -> JsNumber(-1.309197))),
"residents" -> JsArray(Seq(
JsObject(Seq(
"name" -> JsString("Fiver"),
"age" -> JsNumber(4),
"role" -> JsString("")
)),
JsObject(Seq(
"name" -> JsString("Bigwig"),
"age" -> JsNumber(6),
"role" -> JsString("Owsla")
))
))
))
var jsonTMap:Map[String, Any] = Map()
val jsonTString: String = Json.stringify(jsonT)
jsonTMap = jsonStrToMap(jsonTString)
implicit val formats = org.json4s.DefaultFormats
val jsonA: JsValue = Json.obj(
"name" -> "Bob",
"location" -> "Irvine",
"resident" -> "No",
"nick-name" -> "Bigwig",
"age" -> "6",
"role" -> "Owsla",
"car" -> "BMW",
"multiple-residents" -> JsArray(Seq(
JsObject(Seq(
"name" -> JsString("Fiver"),
"age" -> JsNumber(4),
"role" -> JsObject(Seq(
"position" -> JsString("Fiver"),
"" -> JsNumber(4),
"role" -> JsString("janitor")
))
))
))
)
val jsonB: JsValue = Json.obj(
"name" -> "Anrew",
"location" -> JsString("Elmwood Park"),
"resident" -> "Yes",
"nick-name" -> "Drew",
"age" -> JsNumber(4384),
"role" -> "Programmer",
"house" -> JsBoolean(true),
"multiple-residents" -> JsArray(Seq(
JsObject(Seq(
"name" -> JsString("James"),
"age" -> JsNumber(8),
//"role" -> JsObject(Seq(
"position" -> JsString("Sr. Programmer"),
"" -> JsNumber(10),
"role" -> JsString("Serious")
// ))
))
))
)
//Original json object
var jsonAMap:Map[String, Any] = Map()
val jsonAString: String = Json.stringify(jsonA)
jsonAMap = jsonStrToMap(jsonAString)
//Changed json object
var jsonBMap:Map[String, Any] = Map()
val jsonBString: String = Json.stringify(jsonB)
jsonBMap = jsonStrToMap(jsonBString)
var jsonZMap:Map[String, Any] = Map()
val jsonZString: String = Json.stringify(jsonZ)
jsonZMap = jsonStrToMap(jsonZString)
println(Serialization.write(jsonZMap))
println(Serialization.write(compareMaps(jsonZMap)))
//println(jsonTMap)
//println(compareMaps(jsonTMap))
//println(Serialization.write(compareMaps(jsonTMap)))
//println(compareMaps(jsonTMap))
//println(Serialization.write(compareMaps(jsonTMap)))
}
//convert json to Map using json4s library
def jsonStrToMap(jsonStr: String): Map[String, Any] = {
implicit val formats = org.json4s.DefaultFormats
parse(jsonStr).extract[Map[String, Any]]
}
def compareMaps(mapA: Map[String, Any]): Map[String,Any] = {
//deltaMap will store all the differences
var deltaMap = scala.collection.mutable.Map[String, Any]()
var typeOf :String = ""
//for every value in the map, check if it's a map, if it is go into it and do the difference check.
for((key,value) <- mapA){
typeOf = value.getClass.getSimpleName
if(typeOf.matches("Map[0-9]")){
deltaMap += (key -> compareMaps(value.asInstanceOf[Map[String,Any]]))
}else if(typeOf == "$colon$colon"){
deltaMap += (key -> parseList(value.asInstanceOf[List[Any]]))
}else{
deltaMap += (key -> value)
}
}//end of for((key,value) <- mapA
implicit val formats = org.json4s.DefaultFormats
return((scala.collection.immutable.Map() ++ deltaMap))
}//end of compareMaps
def parseList(values: List[Any]): List[Any] = {
var deltaList = new ListBuffer[Any]()
var typeOf :String = ""
for(value <- values){
typeOf = value.getClass.getSimpleName
if(typeOf == "$colon$colon"){
parseList(value.asInstanceOf[List[Any]])
}else{
deltaList += compareMaps(value.asInstanceOf[Map[String, Any]])
}
}
return (deltaList.toList)
}//end of parseList
//end of class
}
答案 0 :(得分:2)
解决。请看上面。我希望这对未来的人有用。