fusenapi/utils/collect/collect.go
2023-06-27 18:09:56 +08:00

205 lines
3.7 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)
fv := srcv.Elem().FieldByName(fieldName)
k := fv.Interface().(KEY)
result[k] = srcv.Interface().(VALUE)
}
return result
}
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 {
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)
var data = make(map[string]interface{})
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
if field.Tag == "" {
continue
}
tag := field.Tag.Get("json")
val := v.Field(i)
if val.Kind() == reflect.Ptr {
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 = s.Elem()
}
structValue := s.Interface()
m := StructJson2Map(structValue)
maps = append(maps, m)
}
return maps
}