在这种情况下,我正在从KV商店(Redis)读取数据。返回的数据采用以下格式。
{ "key1":"value1", "key2":"value2", "key3":"value3" ...}
键为String
,值为Int
。我想将其转换为Map[String,Int]
我查看了json4s JSON API,我的当前代码如下所示。这样做有更好/更容易/更清洁的方法吗?
//send a async query to Redis to
val queryFuture = redis.zrangebyscore[String](tablename, keymin, keymax )
queryFuture.onComplete {
case Success(datarows) =>
println(s"Got %d rows of type %s for the query successfully".format(datarows.length))
val jsonrows = for { x <- datarows.toList }
yield parse(x)
println("Got json rows %d".format(jsonrows.size))
val mapdata = jsonrows.map(x => x.extract[Map[String,String]]).map( x => x.mapValues(_.toInt))
//need to do something with this data now
case Failure(y) =>
println(s" there was some failure in getting the data from Redis")
}
答案 0 :(得分:2)
这对我来说是最简单的方法:
val map = parse("""{"a":"1","b":"2","c":"3"}""")
.children
.collect { case JField(k, JString(v)) => (k, v.toInt) }
.toMap
答案 1 :(得分:1)
不知道json4s,不幸的是你忽略了类型,但猜测jsonrows
可能就像List[(String, String)]
那样你可以做
List(("key1" -> "1"),("key2" -> "2")).map { case (k, v) => (k, v.toInt)}.toMap
顺便说一句,如果你在need to do something with this data now
中说onComplete
- 这只能是一个副作用操作。在您的处理完成之前,将来会更好map
。
答案 2 :(得分:1)
您的Json4s解决方案看起来很好。或者,您可以使用mapField
转换JObject
的字段以及Map[String, Int]
类型的提取值。
val json1 = parse(
"""
|{
| "key1": "1024",
| "key2": "2048",
| "key3": "4096"
|}
""".stripMargin)
val json2 = json1.mapField {
case (key, JString(value)) => (key, JInt(value.toInt))
case x => x
}
val res = json2.extract[Map[String, Int]]
println(res)
// Map(key1 -> 1024, key2 -> 2048, key3 -> 4096)