Go中的list数组筛选

在业务中,我们常常有一些查询是根据某些条件来的,比如在list数据中根据条件匹配相应的数据,常用的做法是通过for循环,然后通过成员单个单个的比较,为方便通用,通过反射做出封装

封装相关方法:

//筛选数组
func GetListByParam(list []interface{}, result interface{}, param map[string]interface{}) error {
	if list == nil {
		return errors.New("source data is nil")
	}
	if param == nil {
		return errors.New("param is nil")
	}
	var resultArr []interface{}
	for _, value := range list {
		refValue := reflect.ValueOf(value)
		isHave := true
		for key, item := range param {
			fieldValue := refValue.FieldByName(key).Interface()
			if fieldValue != item {
				isHave = false
				break
			} else {
				isHave = true
			}
		}
		if isHave {
			resultArr = append(resultArr, value)
		}
	}
	err := InterfaceArrToStructArr(resultArr, result)
	if err != nil {
		return err
	}
	return nil
}

//获取结构体有值的成员
func GetStructMember(model interface{}) (map[string]interface{}, error) {
	if model == nil {
		return nil, errors.New("model is nil")
	}
	resultmap := make(map[string]interface{})
	if model != nil {

		refValue := reflect.ValueOf(model)
		refType := reflect.TypeOf(model)
		fieldCount := refValue.NumField()
		for i := 0; i < fieldCount; i++ {
			fieldType := refType.Field(i)
			fieldValue := refValue.Field(i)
			isadd := false
			switch fieldType.Type.String() {
			case "string":
				if fieldValue.Len() > 0 {
					isadd = true
				}
			case "int", "int8", "int16", "int32", "int64":
				if fieldValue.Int() != 0 {
					isadd = true
				}
			case "time.Time":
				valTime := fieldValue.Interface().(time.Time)
				if !CheckIsDefaultTime(valTime) {
					isadd = true
				}
			}
			if isadd {
				resultmap[refType.Field(i).Name] = fieldValue.Interface()
			}
		}
	}
	return resultmap, nil
}

//InterfaceArrToStructArr Interface数组转为结构体数组
func InterfaceArrToStructArr(src []interface{}, model interface{}) error {
	val := reflect.Indirect(reflect.ValueOf(model))
	typ := val.Type()
	for _, r := range src {
		mVal := reflect.Indirect(reflect.New(typ.Elem().Elem())).Addr()
		fmt.Println(r)
		fmt.Println(mVal.Interface())
		IntfaceToStruct(r, mVal.Interface())
		val = reflect.Append(val, mVal)
	}
	DeepCopy(model, val.Interface())
	return nil
}

//IntfaceToStruct IntfaceToStruct 通过json过渡,结构体互相转化
func IntfaceToStruct(mapSrc interface{}, dst interface{}) error {
	//待优化
	bytes, err := json.Marshal(mapSrc)
	err = json.Unmarshal(bytes, &dst)
	return err
}

func DeepCopy(dst, src interface{}) error {
	var buf bytes.Buffer
	if err := gob.NewEncoder(&buf).Encode(src); err != nil {
		return err
	}
	return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
}

  

调用方式:

model = &hostmodels.HostsModel{Gid: 1, CdnName: ""}
results := make([]*hostmodels.HostsModel, 0)
list := make([]interface{}, 0)
list = append(list,new(hostmodels.HostsModel){})
mapQuery, _ := GetStructMember(*model) 
err = GetListByParam(list, &results, mapQuery) if err != nil { return nil, err } //排序 sort.SliceStable(results, func(i, j int) bool { return results[i].Gid < results[j].Gid })

  

posted @ 2021-09-10 13:56  MrZhaoLin  阅读(899)  评论(0编辑  收藏  举报