使用转换函数对 AST 进行后处理以重命名 json 字段名称时出现奇怪的行为

发布于 2024-10-01 04:54:05 字数 1985 浏览 5 评论 0原文

我很可能做错了,但事情就是这样。我正在使用 lift-json 将 json 响应字符串转换为对象。我得到的响应字符串有一些字段名称,这些名称不是在 Scala 中使用的最佳主意,即选项。我想编写一个“帮助器”函数,它几乎只是 JValue.transform 的包装器:

def renameFields(originalJson : JValue, oldFieldName : String, newFieldName : String): JValue = {
    originalJson transform { case JField(oldFieldName,x) => JField(newFieldName, x)}
}

这是我正在使用的示例响应字符串和 JObject:

scala> val jstring = """ { "aisle" : 1, "bin" : 1, "hasWhat" : [{ "id" : 4, "name" : "Granny", "color" : "green"}, { "id" : 4, "name" : "Fuji", "color" : "red"}] }"""
jstring: java.lang.String =  { "aisle" : 1, "bin" : 1, "hasWhat" : [{ "id" : 4, "name" : "Granny", "color" : "green"}, { "id" : 4, "name" : "Fuji", "color" : "red"}] }

scala> val json = parse(jstring)
json: net.liftweb.json.JsonAST.JValue = JObject(List(JField(aisle,JInt(1)), JField(bin,JInt(1)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(4)), JField(name,JString(Granny)), JField(color,JString(green)))), JObject(List(JField(id,JInt(4)), JField(name,JString(Fuji)), JField(color,JString(red)))))))))

如果我使用此函数,所有字段名称最终都会更改:

scala> Util.renameFields(json,"aisle","row")
res2: net.liftweb.json.JsonAST.JValue = JObject(List(JField(row,JInt(1)), JField(row,JInt(1)), JField(row,JArray(List(JObject(List(JField(row,JInt(4)), JField(row,JString(Granny)), JField(row,JString(green)))), JObject(List(JField(row,JInt(4)), JField(row,JString(Fuji)), JField(row,JString(red)))))))))

而我真正想要的是:

scala> json transform { case JField("aisle",x) => JField("row",x) }
res3: net.liftweb.json.JsonAST.JValue = JObject(List(JField(row,JInt(1)), JField(bin,JInt(1)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(4)), JField(name,JString(Granny)), JField(color,JString(green)))), JObject(List(JField(id,JInt(4)), JField(name,JString(Fuji)), JField(color,JString(red)))))))))

那么……我做错了什么?提前致谢。

-还是新手

Chances are that I am doing this wrong, but here goes. I'm using lift-json to turn a json response string into an object. The response string I get has some names for fields that aren't the best idea to use in Scala, i.e. option. I wanted to write a "helper" function that is pretty much just a wrapper around JValue.transform:

def renameFields(originalJson : JValue, oldFieldName : String, newFieldName : String): JValue = {
    originalJson transform { case JField(oldFieldName,x) => JField(newFieldName, x)}
}

Here is the sample response string and JObject I'm working with:

scala> val jstring = """ { "aisle" : 1, "bin" : 1, "hasWhat" : [{ "id" : 4, "name" : "Granny", "color" : "green"}, { "id" : 4, "name" : "Fuji", "color" : "red"}] }"""
jstring: java.lang.String =  { "aisle" : 1, "bin" : 1, "hasWhat" : [{ "id" : 4, "name" : "Granny", "color" : "green"}, { "id" : 4, "name" : "Fuji", "color" : "red"}] }

scala> val json = parse(jstring)
json: net.liftweb.json.JsonAST.JValue = JObject(List(JField(aisle,JInt(1)), JField(bin,JInt(1)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(4)), JField(name,JString(Granny)), JField(color,JString(green)))), JObject(List(JField(id,JInt(4)), JField(name,JString(Fuji)), JField(color,JString(red)))))))))

If I use this function, all the field names end up getting changed:

scala> Util.renameFields(json,"aisle","row")
res2: net.liftweb.json.JsonAST.JValue = JObject(List(JField(row,JInt(1)), JField(row,JInt(1)), JField(row,JArray(List(JObject(List(JField(row,JInt(4)), JField(row,JString(Granny)), JField(row,JString(green)))), JObject(List(JField(row,JInt(4)), JField(row,JString(Fuji)), JField(row,JString(red)))))))))

And what I actually want is:

scala> json transform { case JField("aisle",x) => JField("row",x) }
res3: net.liftweb.json.JsonAST.JValue = JObject(List(JField(row,JInt(1)), JField(bin,JInt(1)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(4)), JField(name,JString(Granny)), JField(color,JString(green)))), JObject(List(JField(id,JInt(4)), JField(name,JString(Fuji)), JField(color,JString(red)))))))))

So...what am I doing wrong? Thanks in advance.

-Still Newbie

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鲜血染红嫁衣 2024-10-08 04:54:06

我认为您缺少的只是 oldFieldName 周围的反引号:

scala> def renameFields(originalJson : JValue, oldFieldName : String, newFieldName : String): JValue = originalJson transform { case JField(`oldFieldName`,x) => JField(newFieldName, x)}
renameFields: (originalJson: net.liftweb.json.JsonAST.JValue,oldFieldName: String,newFieldName: String)net.liftweb.json.JsonAST.JValue

scala> val jstring = """ { "aisle" : 1, "bin" : 1, "hasWhat" : [{ "id" : 4, "name" : "Granny", "color" : "green"}, { "id" : 4, "name" : "Fuji", "color" : "red"}] }"""
jstring: java.lang.String =  { "aisle" : 1, "bin" : 1, "hasWhat" : [{ "id" : 4, "name" : "Granny", "color" : "green"}, { "id" : 4, "name" : "Fuji", "color" : "red"}] }

scala> val json = parse(jstring)
json: net.liftweb.json.JsonAST.JValue = JObject(List(JField(aisle,JInt(1)), JField(bin,JInt(1)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(4)), JField(name,JString(Granny)), JField(color,JString(green)))), JObject(List(JField(id,JInt(4)), JField(name,JString(Fuji)), JField(color,JString(red)))))))))

scala> renameFields(json,"aisle","row")
res0: net.liftweb.json.JsonAST.JValue = JObject(List(JField(row,JInt(1)), JField(bin,JInt(1)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(4)), JField(name,JString(Granny)), JField(color,JString(green)))), JObject(List(JField(id,JInt(4)), JField(name,JString(Fuji)), JField(color,JString(red)))))))))

如果没有反引号,case JField(oldFieldName,x) 会说“将我找到的任何值绑定为 JField 名称到新变量 oldFieldName”,因此您的原始 oldFieldName 变量被隐藏。通过 oldFieldName 周围的反引号,您表示您只想匹配名称为 oldFieldName 值的 JField

I think all you're missing is backticks around oldFieldName:

scala> def renameFields(originalJson : JValue, oldFieldName : String, newFieldName : String): JValue = originalJson transform { case JField(`oldFieldName`,x) => JField(newFieldName, x)}
renameFields: (originalJson: net.liftweb.json.JsonAST.JValue,oldFieldName: String,newFieldName: String)net.liftweb.json.JsonAST.JValue

scala> val jstring = """ { "aisle" : 1, "bin" : 1, "hasWhat" : [{ "id" : 4, "name" : "Granny", "color" : "green"}, { "id" : 4, "name" : "Fuji", "color" : "red"}] }"""
jstring: java.lang.String =  { "aisle" : 1, "bin" : 1, "hasWhat" : [{ "id" : 4, "name" : "Granny", "color" : "green"}, { "id" : 4, "name" : "Fuji", "color" : "red"}] }

scala> val json = parse(jstring)
json: net.liftweb.json.JsonAST.JValue = JObject(List(JField(aisle,JInt(1)), JField(bin,JInt(1)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(4)), JField(name,JString(Granny)), JField(color,JString(green)))), JObject(List(JField(id,JInt(4)), JField(name,JString(Fuji)), JField(color,JString(red)))))))))

scala> renameFields(json,"aisle","row")
res0: net.liftweb.json.JsonAST.JValue = JObject(List(JField(row,JInt(1)), JField(bin,JInt(1)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(4)), JField(name,JString(Granny)), JField(color,JString(green)))), JObject(List(JField(id,JInt(4)), JField(name,JString(Fuji)), JField(color,JString(red)))))))))

Without the backticks, case JField(oldFieldName,x) is saying "bind whatever value I find as the JField name to the new variable oldFieldName" and thus your original oldFieldName variable is shadowed. With the backticks around oldFieldName, you're saying you only want to match a JField whose name is the value of oldFieldName.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文