281 lines
5.3 KiB
Go
281 lines
5.3 KiB
Go
package collect
|
|
|
|
import (
|
|
"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] = arr.Index(i).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] = arr.Index(i).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
|
|
}
|
|
|
|
// LoadJsonTag 根据loader的json tag 赋值 给拥有相同json tag
|
|
func LoadJsonTag(v interface{}, loaded interface{}) {
|
|
vtype := reflect.TypeOf(v)
|
|
if vtype.Kind() != reflect.Ptr {
|
|
panic("v must is a pointer")
|
|
}
|
|
vtype = vtype.Elem()
|
|
|
|
var vvalue reflect.Value
|
|
if vtype.Kind() == reflect.Ptr {
|
|
vtype = vtype.Elem()
|
|
vvalue = reflect.ValueOf(v).Elem().Elem()
|
|
} else {
|
|
vvalue = reflect.ValueOf(v).Elem()
|
|
}
|
|
|
|
ltype := reflect.TypeOf(loaded)
|
|
if ltype.Kind() != reflect.Ptr {
|
|
panic("loaded must is a pointer")
|
|
}
|
|
ltype = ltype.Elem()
|
|
var lvalue reflect.Value
|
|
if ltype.Kind() == reflect.Ptr {
|
|
ltype = ltype.Elem()
|
|
lvalue = reflect.ValueOf(loaded).Elem().Elem()
|
|
} else {
|
|
lvalue = reflect.ValueOf(loaded).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)
|
|
|
|
if vv.Kind() == reflect.Ptr {
|
|
|
|
if lv.Kind() == reflect.Ptr {
|
|
vv.Set(lv)
|
|
} else {
|
|
x := reflect.New(vv.Type().Elem())
|
|
x.Elem().Set(lv)
|
|
vv.Set(x)
|
|
}
|
|
|
|
} else {
|
|
|
|
if lv.Kind() != reflect.Ptr {
|
|
vv.Set(lv)
|
|
} else {
|
|
vv.Set(lv.Elem())
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|