1

在这种情况下,我正在从 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")
  }
4

3 回答 3

2

这在我看来是最简单的方法:

val map = parse("""{"a":"1","b":"2","c":"3"}""")
  .children
  .collect { case JField(k, JString(v)) => (k, v.toInt) }
  .toMap
于 2014-03-30T04:41:34.303 回答
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未来会更好,直到您的处理完成。

于 2014-03-29T08:19:54.783 回答
1

您的 Json4s 解决方案看起来不错。或者,您可以使用mapField转换 a 的字段,JObject然后提取 type 的值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)
于 2014-03-29T22:36:29.760 回答