package collect import ( "log" "reflect" "strconv" ) func ArrayColumn[R any, T any](arr []T, column string) []R { defer func() { if err := recover(); err != nil { panic(err) } }() var result []R s := reflect.ValueOf(arr) for i := 0; i < s.Len(); i++ { e := s.Index(i) if e.Kind() == reflect.Ptr { e = e.Elem() } k := e.FieldByName(column) if k.Kind() == reflect.Ptr { k = k.Elem() } result = append(result, k.Interface().(R)) } return result } func ArrayColumnTag[R any, T any](arrSrc []T, tag string) []R { defer func() { if err := recover(); err != nil { panic(err) } }() var result []R arr := reflect.ValueOf(arrSrc) if arr.Len() == 0 { return result } ele := arr.Index(0) if ele.Kind() == reflect.Ptr { ele = ele.Elem() } eleType := ele.Type() for j := 0; j < eleType.NumField(); j++ { if value, ok := eleType.Field(j).Tag.Lookup("json"); ok && value == tag { for i := 0; i < arr.Len(); i++ { srcv := arr.Index(i) if srcv.Kind() == reflect.Ptr { srcv = srcv.Elem() } fv := srcv.Field(j) if fv.Kind() == reflect.Ptr { fv = fv.Elem() } result = append(result, fv.Interface().(R)) } return result } } return result } func ArrayIndex[T any](arr []T, index int) (result T, ok bool) { if index < len(arr) { result = arr[index] ok = true return } ok = false return } func ArrayString2Int(arr interface{}) (result []int64) { defer func() { if err := recover(); err != nil { panic(err) } }() for _, a := range arr.([]string) { v, err := strconv.ParseInt(a, 10, 64) if err != nil { panic(err) } result = append(result, v) } return result } func Array2MapByKey[KEY comparable, VALUE any](arrSrc []VALUE, fieldName string) (result map[KEY]VALUE) { defer func() { if err := recover(); err != nil { panic(err) } }() result = make(map[KEY]VALUE) arr := reflect.ValueOf(arrSrc) for i := 0; i < arr.Len(); i++ { srcv := arr.Index(i) if srcv.Kind() == reflect.Ptr { if srcv.IsNil() { continue } srcv = srcv.Elem() } fv := srcv.FieldByName(fieldName) k := fv.Interface().(KEY) result[k] = srcv.Interface().(VALUE) } return result } // 一个数组slice转换成 map[tag]slice ,以slice元素的某个tag为map func Array2MapByKeyTag[KEY comparable, VALUE any](arrSrc []VALUE, tag string) (result map[KEY]VALUE) { defer func() { if err := recover(); err != nil { panic(err) } }() arr := reflect.ValueOf(arrSrc) if arr.Len() == 0 { return result } result = make(map[KEY]VALUE) ele := arr.Index(0) if ele.Kind() == reflect.Ptr { ele = ele.Elem() } eleType := ele.Type() for j := 0; j < eleType.NumField(); j++ { if value, ok := eleType.Field(j).Tag.Lookup("json"); ok && value == tag { for i := 0; i < arr.Len(); i++ { srcv := arr.Index(i) var fv reflect.Value if srcv.Kind() == reflect.Ptr { if srcv.IsNil() { continue } fv = srcv.Elem().Field(j) } else { fv = srcv.Field(j) } if fv.Kind() == reflect.Ptr { fv = fv.Elem() } k := fv.Interface().(KEY) result[k] = srcv.Interface().(VALUE) } return } } return result } func StructJson2Map(s interface{}) map[string]interface{} { t := reflect.TypeOf(s) v := reflect.ValueOf(s) if v.Kind() == reflect.Ptr { v = v.Elem() } var data = make(map[string]interface{}) for i := 0; i < t.NumField(); i++ { field := t.Field(i) if tag, ok := field.Tag.Lookup("json"); ok { val := v.Field(i) if val.Kind() == reflect.Ptr && !val.IsNil() { val = val.Elem() } data[tag] = val.Interface() } } return data } func StructSliceJson2Maps(s interface{}) []map[string]interface{} { slice := reflect.ValueOf(s) var maps []map[string]interface{} for i := 0; i < slice.Len(); i++ { s := slice.Index(i) if s.Kind() == reflect.Ptr && !s.IsNil() { s = s.Elem() } structValue := s.Interface() m := StructJson2Map(structValue) maps = append(maps, m) } return maps } func LoadJsonTag(v interface{}, loaded interface{}) { vtype := reflect.TypeOf(v) if vtype.Kind() == reflect.Ptr { vtype = vtype.Elem() } vvalue := reflect.ValueOf(v) if vvalue.Kind() == reflect.Ptr { vvalue = vvalue.Elem() } ltype := reflect.TypeOf(loaded) if ltype.Kind() == reflect.Ptr { ltype = ltype.Elem() } lvalue := reflect.ValueOf(loaded) if lvalue.Kind() == reflect.Ptr { lvalue = lvalue.Elem() } for i := 0; i < vtype.NumField(); i++ { vfield := vtype.Field(i) if vtag, ok := vfield.Tag.Lookup("json"); ok { for j := 0; j < ltype.NumField(); j++ { lfield := ltype.Field(j) if ltag, ok := lfield.Tag.Lookup("json"); ok && vtag == ltag { vv := vvalue.Field(i) lv := lvalue.Field(j) log.Println(vv.Kind(), vv.Type().Elem(), lv.Kind()) if vv.Kind() == reflect.Ptr { if lv.Kind() == reflect.Ptr { vv.Set(lv) } else { vv = reflect.New(vv.Type().Elem()) log.Println(vv.Type().Kind(), vv.Elem().Kind(), lv, reflect.Indirect(vv)) reflect.Indirect(vv.Addr()).Set(lv.Addr()) vv = reflect.New(vv.Type().Elem()) vv.Set(lv.Addr()) } vv.Set(lv) } else { if lv.Kind() != reflect.Ptr { vv.Set(lv) } else { vv.Set(lv.Elem()) } } } } } } }