需求
针对 json数据里的user_name进行模糊搜索,返回匹配的列
参考数据
json
[
{
"id": 122,
"name": "sgm_info40_b233 5.5_plus",
"logo": "https://bj.bcebos.com/v1/iov-recom/car_default.png",
"user_name": "张三",
"user_id": "838024601",
"status": 0,
"product_no": "",
"product_status": "",
"sdk_id": "",
"kernel_no": "1.0.1",
"dumi_appid": "",
"dumi_appname": "iov_sgm_b233_2021",
"dumi_appversion": "5.5_plus",
"create_time": "2024-09-11 10:52:18",
"update_time": ""
},
{
"id": 123,
"name": "sgm_info40_b223 5.5",
"logo": "https://bj.bcebos.com/v1/iov-recom/car_default.png",
"user_name": "李四",
"user_id": "838024601",
"status": 0,
"product_no": "",
"product_status": "",
"sdk_id": "",
"kernel_no": "1.0.1",
"dumi_appid": "",
"dumi_appname": "iov_sgm_b223_2021",
"dumi_appversion": "5.5",
"create_time": "2024-09-11 10:55:18",
"update_time": ""
}
]
实现
go
package main
import (
"encoding/json"
"fmt"
"strings"
)
type Data struct {
ID int `json:"id"`
Name string `json:"name"`
Logo string `json:"logo"`
UserName string `json:"user_name"`
UserID string `json:"user_id"`
Status int `json:"status"`
ProductNo string `json:"product_no"`
ProductStatus string `json:"product_status"`
SdkID string `json:"sdk_id"`
KernelNo string `json:"kernel_no"`
DumiAppID string `json:"dumi_appid"`
DumiAppName string `json:"dumi_appname"`
DumiAppVersion string `json:"dumi_appversion"`
CreateTime string `json:"create_time"`
UpdateTime string `json:"update_time"`
}
// FilterByField 根据字段进行模糊匹配
func FilterByField[T any](data []T, fieldName string, keyword string) []T {
matched := make([]T, 0)
for _, item := range data {
// 获取结构体的反射值
val := reflect.ValueOf(item)
// 检查 val 是结构体类型,若 val 是指针需要先解引用
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
// 获取字段值
fieldVal := val.FieldByName(fieldName)
if fieldVal.IsValid() && fieldVal.Kind() == reflect.String {
// 如果字段是字符串类型,进行模糊匹配
if strings.Contains(fieldVal.String(), keyword) {
matched = append(matched, item)
}
}
}
return matched
}
func main() {
jsonData := `[
{
"id": 97,
"name": "sgm_info40_l233 7",
"logo": "https://bj.bcebos.com/v1/iov-recom/car_default.png",
"user_name": "张三",
"user_id": "838024601",
"status": 0,
"product_no": "",
"product_status": "",
"sdk_id": "",
"kernel_no": "1.0.1",
"dumi_appid": "",
"dumi_appname": "iov_sgm_info40_l233",
"dumi_appversion": "7",
"create_time": "2024-03-07 11:43:07",
"update_time": ""
},
{
"id": 98,
"name": "sgm_info40_l232 1",
"logo": "https://bj.bcebos.com/v1/iov-recom/car_default.png",
"user_name": "李四",
"user_id": "838024601",
"status": 0,
"product_no": "",
"product_status": "",
"sdk_id": "",
"kernel_no": "1.0.1",
"dumi_appid": "",
"dumi_appname": "iov_sgm_info40_l232",
"dumi_appversion": "1",
"create_time": "2024-03-07 15:03:29",
"update_time": ""
},
{
"id": 110,
"name": "sgm_info40_u458 5.5",
"logo": "https://bj.bcebos.com/v1/iov-recom/car_default.png",
"user_name": "王五",
"user_id": "838024601",
"status": 0,
"product_no": "",
"product_status": "",
"sdk_id": "",
"kernel_no": "1.0.1",
"dumi_appid": "",
"dumi_appname": "iov_sgm_info40_u458",
"dumi_appversion": "5.5",
"create_time": "2024-07-25 11:23:44",
"update_time": ""
},
{
"id": 111,
"name": "sgm_info40_3582_hev 5.5",
"logo": "https://bj.bcebos.com/v1/iov-recom/car_default.png",
"user_name": "张三",
"user_id": "838024601",
"status": 0,
"product_no": "",
"product_status": "",
"sdk_id": "",
"kernel_no": "1.0.1",
"dumi_appid": "",
"dumi_appname": "iov_sgm_info40_3582_hev",
"dumi_appversion": "5.5",
"create_time": "2024-07-25 11:23:44",
"update_time": ""
}
]`
var data []Data
err := json.Unmarshal([]byte(jsonData), &data)
if err != nil {
fmt.Println("Error parsing JSON:", err)
return
}
// 模糊搜索 user_name 包含 "张"
result := FilterByField(data, "UserName", "张")
// 打印结果
for _, item := range result {
fmt.Printf("ID: %d, UserName: %s, Name: %s\n", item.ID, item.UserName, item.Name)
}
}
输出结果
ID: 97, UserName: 张三, Name: sgm_info40_l233 7
ID: 111, UserName: 张三, Name: sgm_info40_3582_hev 5.5
解释:
- 泛型函数 FilterByField:这是一个使用泛型的公共方法,接受一个任意类型的切片,并根据指定的字段名进行模糊匹配。这里使用了 reflect 包来动态获取字段的值。
- reflect.ValueOf(item):通过反射获取结构体的字段值。
- FieldByName(fieldName):根据字段名获取对应的字段值,并判断其类型是否为字符串。
- strings.Contains:对字段值进行模糊匹配。
- fieldVal.IsValid(): 判断通过反射获取的字段值是否有效。具体来说,IsValid() 返回一个布尔值,如果字段存在并且可访问,返回 true,否则返回 false。
- fieldVal.Kind(): 返回一个 reflect.Kind 值,用于表示通过反射获取到的值的基础类型。Kind() 是枚举类型,表示 Go 中的基本类型,例如 reflect.String, reflect.Int, reflect.Struct 等。使用 Kind() 可以检查字段的数据类型,然后根据类型执行不同的操作。
- val.Elem():检查 输入对象是结构体类型,若是指针需要通过Elem()先解引用。
优点:
泛型使得这个方法可以适用于任何结构体类型。
反射使得可以通过字段名动态访问字段。