使用gjson查询含随机键的JSON,获取指定条件键名遇空输出问题
使用GJSON获取JSON对象中满足条件的随机键名
你的问题出在GJSON语法的误用:#是针对数组元素的筛选语法,但cars是一个JSON对象(键为随机字符串),而非数组,所以原查询无法匹配到任何内容。以下是两种直接可行的解决方法:
方法1:用GJSON查询表达式实现一键筛选
利用GJSON的管道|和@key(获取当前对象的键名)特性,配合条件筛选:
package main import "github.com/tidwall/gjson" func main() { jsonStr := `{ "cars":{ "dfhuidsfiusd":{ "name":"Mercedes", "details": { "plate_number":"sas2-hd-3", "year": 2009 } }, "uiwouiouss":{ "name":"Jaguar", "details": { "plate_number":"sas2-hd-3", "year": 2009 } }, "sdikdshkjsd":{ "name":"Toyota", "details": { "plate_number":"sas2-hd-3", "year": 2009 } } } }` // 筛选出details.year=2009的键名 result := gjson.Get(jsonStr, `cars.*|@key|#(parent.details.year == 2009)`) for _, key := range result.Array() { println(key.String()) } }
语法拆解:
cars.*:遍历cars对象下的所有子对象|@key:提取每个子对象对应的键名|#(parent.details.year == 2009):筛选出父级对象中details.year等于2009的键名
方法2:用ForEach遍历键值对(更灵活)
如果需要后续扩展筛选逻辑,直接遍历cars的键值对会更直观:
package main import "github.com/tidwall/gjson" func main() { jsonStr := `{ "cars":{ "dfhuidsfiusd":{ "name":"Mercedes", "details": { "plate_number":"sas2-hd-3", "year": 2009 } }, "uiwouiouss":{ "name":"Jaguar", "details": { "plate_number":"sas2-hd-3", "year": 2009 } }, "sdikdshkjsd":{ "name":"Toyota", "details": { "plate_number":"sas2-hd-3", "year": 2009 } } } }` gjson.Get(jsonStr, "cars").ForEach(func(key, value gjson.Result) bool { // 判断当前对象的details.year是否符合条件 if value.Get("details.year").Int() == 2009 { println(key.String()) } return true // 返回true继续遍历,返回false终止遍历 }) }
原代码失效原因
cars.#是数组索引语法,仅适用于JSON数组,而cars是对象,无法匹配任何元素details(year="2009")的筛选语法不适用于对象的遍历场景,无法正确关联到父级键名
内容的提问来源于stack exchange,提问作者badman
相关产品推荐
相关产品推荐

