【问题标题】:Modifying a JSON object with lift-json使用 lift-json 修改 JSON 对象
【发布时间】:2014-04-14 04:25:15
【问题描述】:

我正在选择一个好的 Scala JSON 库,共识似乎是 lift-json 是目前最好的选择。

在使用它(2.5.1 版)一段时间后,我已经能够相当轻松地完成大部分我需要的事情,除了一个:修改现有的JValue

假设我有以下JValue 的实例:

val john = ("id"   -> 1) ~
           ("name" -> "Foo") ~
           ("nested" ->
             ("id" -> 2) ~
             ("name" -> "Bar"))

我想将父元素的名称从 Foo 更改为 foo。我认为transform 方法是可行的方法:

john transform {
    case JField("name", _) => JField("name", "foo")
})

但这会将父元素和嵌套元素的 name 字段更改为 foo - 回想起来,这真的不应该让人感到意外。

我查看了文档和代码,但找不到选择键为 name 的特定字段的方法。我错过了什么吗?

另一种解决方案(这个可行)似乎是合并两个 JValue 对象,但似乎有点冗长:

john merge JObject(JField("name", "foo") :: Nil)

是否有一种内置的、更易读的方法来实现相同的结果?我可能可以写一个从JFieldJObject 的隐式转换,但lift-json 还没有这样的机制似乎很奇怪。如果我必须打赌,那就是我没有找到它,而不是它不存在。

编辑:我现在觉得有点傻

john transform {
    case JField("name", "Foo") => JField("name", "foo")
})

不是世界上最佳的解决方案,但可读性和简洁性完美。

【问题讨论】:

    标签: scala lift-json


    【解决方案1】:

    这很难看,因为它使用了一个可变变量,而且它还使用了 json4s(它在后台使用 lift-json),但它确实有效:

    import org.json4s.JsonAST._
    import org.json4s.native.JsonMethods._
    import org.json4s.JsonDSL._
    
    object JsonTesting {
      def main(args: Array[String]) {
        val john = ("id"   -> 1) ~
               ("name" -> "Foo") ~
               ("nested" ->
                 ("id" -> 2) ~
                 ("name" -> "Bar"))
    
        var changed = false
        val john2 = john transformField {
          case JField("name", _) if !changed => 
            changed = true
            JField("name", "foo")
        }
      }
    }
    

    我找不到更简洁的方法来告诉它要么只遍历一个深度级别,要么知道每个检查节点的深度,所以我只会在第一级深度上进行切换。

    【讨论】:

      【解决方案2】:

      像这样使用 JValue 的replace 方法:

      john.replace(List("name"), "foo")

      这种“替换”方法的实现是一场灾难,并且名称替换(对我而言)暗示了一种不正确但确实有效的状态修改

      JObject(List((id,JInt(1)), (name,JString(foo)), (nested,JObject(List((id,JInt(2)), (name,JString(Bar)))))))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-14
        • 1970-01-01
        • 1970-01-01
        • 2017-09-11
        • 1970-01-01
        • 2011-06-13
        • 1970-01-01
        • 2017-08-19
        相关资源
        最近更新 更多