Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用transform函数对AST进行后处理以重命名json字段名的奇怪行为_Json_Scala_Transform_Rename_Lift - Fatal编程技术网

使用transform函数对AST进行后处理以重命名json字段名的奇怪行为

使用transform函数对AST进行后处理以重命名json字段名的奇怪行为,json,scala,transform,rename,lift,Json,Scala,Transform,Rename,Lift,很可能我做错了,但事情是这样的。我使用lift json将json响应字符串转换为对象。我得到的响应字符串中有一些字段的名称,这些字段在Scala中不是最好使用的,例如option。我想编写一个“helper”函数,它几乎只是JValue.transform的包装器: def renameFields(originalJson : JValue, oldFieldName : String, newFieldName : String): JValue = { originalJson

很可能我做错了,但事情是这样的。我使用lift json将json响应字符串转换为对象。我得到的响应字符串中有一些字段的名称,这些字段在Scala中不是最好使用的,例如option。我想编写一个“helper”函数,它几乎只是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)))))))))
那么…我做错了什么?提前谢谢


-仍然是新手

我想你所缺少的是关于
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
周围有反勾号,表示您只想匹配一个
JField
,其名称是
oldFieldName

(在此处插入墙bash)的值。缺少反勾号/前勾号/引号的诅咒。谢谢Steve,我从来没有想过在方法中使用任何类型的勾号或引号。出于好奇,你是怎么知道要这么做的?我想可能是因为阅读了这篇文章,特别是“在模式匹配中使用以小写字母开头的标识符”的答案提到了反勾号。再次感谢Steve!这是一个非常有用的帖子。