这一切都来源于一个蛋疼的需求场景处理:
因为历史原因,一个需要用到的 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"
}
怎么说呢,实现了感觉又没有真正实现...
哎,蛋疼。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于