Go语言:判断对象数组中是否存在属性匹配指定值的元素并返回索引
需求背景
对接API拿到的响应是如下结构的JSON数组:
[ { "id": "F1eOrsr3g7gad6", "created_at": 1591951315, "url": "https://example.com", "secret": "1234", "secret_exists": true }, { "id": "FintcvTBaYwPz2", "created_at": 1591953315, "url": "http://example.com", "secret": "34532", "secret_exists": true } ]
现在需要校验数组中是否存在指定属性值的对象,比如检查是否存在id字段值为F1eOrsr3g7gad6的元素。
目前已编写查询函数,逻辑为匹配到目标值时返回对应元素的索引,匹配失败返回-1,示例代码如下:
func isExists(key string, value string, data []map[string]interface{}) (result int) { result = -1 for i, search := range data { if search[key] == value { result = i break } } return result } var value string = "FintcvTBaYwPz2" var key string = "id" result := isExists(key, value, data) // 此处data为待传入查询的目标数组 fmt.Println("Result: ", result)
代码说明与优化
- 上述代码的遍历匹配逻辑完全可行,针对给出的示例数组,查询
id为FintcvTBaYwPz2的元素时,会匹配到数组索引为1的元素,最终输出Result: 1;如果查询值不存在,就会返回-1。 - 原有判断逻辑存在健壮性不足的问题:直接做值对比前没有加类型校验,当JSON反序列化后对应键的值因为结构不匹配、键名拼写错误变成
nil或者其他类型时,代码不会抛出报错,但会永远匹配不到目标值。 - 增加类型断言可以解决这个问题,把原有匹配判断替换为以下代码即可:
// 先校验对应键的值是否为字符串类型,再做值对比 if v, ok := search[key].(string); ok && v == value { result = i break }
效率提示:如果数组元素规模较大,且需要频繁按指定键查询,可以提前把数组转换为以目标键为键、对应元素内容/索引为值的映射表,把循环遍历的O(n)查询优化为O(1)的哈希查询,降低重复查询的性能开销。
内容的提问来源于stack exchange,提问作者ManuGN
相关产品推荐
相关产品推荐

