这一切都来源于一个蛋疼的需求场景处理:
因为历史原因,一个需要用到的JSON数据被整个缓存进Redis的一个key中,大概如下:
127.0.0.1:6379> get dt
"{\"address\":[{\"duration\":90,\"format\":\"mp4\",\"url\":\"xxx.mp4\",\"ext\":\"{\\\"key\\\":\\\"val\\\"}\"},{\"duration\":90,\"format\":\"mp4\",\"url\":\"xxx.mp4\",\"ext\":\"{\\\"key\\\":\\\"val\\\"}\"}],\"value\":\"web\"}"
127.0.0.1:6379>
这里还是做了脱敏处理,实际的情形JSON的层级更深…
格式化显示的JSON结构大概是这样:
{
"address": [
{
"duration": 90,
"format": "mp4",
"url": "xxx.mp4",
"ext": "{\"key\":\"val\"}"
},
{
"duration": 90,
"format": "mp4",
"url": "xxx.mp4",
"ext": "{\"key\":\"val\"}"
}
],
"value": "web"
}
现在要做的是: address 里的每个元素的 url 字段需要更新。
现在知道的是:address 的值 是一个数组,数组的每个元素是一个map[string]interface{} 类型,map里的元素除了 “url”: “xxx.mp4”, 其他的数量不确定
实现代码大概如下(方便展示,省略了Redis读写的步骤):
detailByte := []byte(`{"address":[{"duration":90,"format":"mp4","url":"xxx.mp4","ext":"{\"key\":\"val\"}"},{"duration":90,"format":"mp4","url":"xxx.mp4","ext":"{\"key\":\"val\"}"}],"value":"web"}`)
detail := make(map[string]interface{}, 0)
json.Unmarshal(detailByte, &detail)
formatJson, _ := json.MarshalIndent(detail, "", " ")
fmt.Println("before: ", string(formatJson))
if address, ok := detail["address"]; ok {
if item, ok2 := address.([]interface{}); ok2 {
for index, value := range item {
if vMap, ok3 := value.(map[string]interface{}); ok3 {
if _, ok4 := vMap["url"];ok4 {
vMap["url"] = "wtf.mp4"
}
item[index] = vMap
}
}
detail["address"] = item
}
}
formatJson, _ = json.MarshalIndent(detail, "", " ")
fmt.Println("after: ", string(formatJson))
运行结果:
before: {
"address": [
{
"duration": 90,
"ext": "{\"key\":\"val\"}",
"format": "mp4",
"url": "xxx.mp4"
},
{
"duration": 90,
"ext": "{\"key\":\"val\"}",
"format": "mp4",
"url": "xxx.mp4"
}
],
"value": "web"
}
after: {
"address": [
{
"duration": 90,
"ext": "{\"key\":\"val\"}",
"format": "mp4",
"url": "wtf.mp4"
},
{
"duration": 90,
"ext": "{\"key\":\"val\"}",
"format": "mp4",
"url": "wtf.mp4"
}
],
"value": "web"
}
怎么说呢,实现了感觉又没有真正实现…
哎,蛋疼。
1 comment
在一个论坛上看到一个处理类似问题的JSON库:”github.com/tidwall/sjson”
可以这么操作: value, _ := sjson.Set(json, “address.#.url”, “wtf.mp4”)
妙啊!