最近写代码发现go没有关于slice转map的包或者网上也没有写的靠谱的转化代码,但是现实场景中,我们很容易遇到这种问题,就是获取到的slice []struct 数据类型,我们需要将它转化成map之后被其他的代码取用,废话不多说,我们开始;
首先肯定是需要用到反射reflect进行通用化,不然的话无法试用所有的方法。直接贴代码:
package main
import (
"fmt"
_ "go/types"
"reflect"
)
type User struct {
Age int `json:"age"`
Name string `json:"name"`
Sex string `json:"sex"`
Education int `json:"education"`
}
func main() {
var list []User
info1 := User{
Age:11,
Name:"周杰伦1",
Sex:"man",
Education:10000,
}
info2 := User{
Age:12,
Name:"周杰伦2",
Sex:"man",
Education:20000,
}
info3 := User{
Age:13,
Name:"周杰伦3",
Sex:"man",
Education:30000,
}
list = append(list, info1)
list = append(list, info2)
list = append(list, info3)
mapInfo := Slice2Map(list, "Name")
mapInfo1 := Slice2Map(list, "Age")
mapInfo2 := Slice2Map(list, "Education")
fmt.Printf("获取到的map1是:%+v \n", mapInfo)
fmt.Printf("获取到的map2是:%+v \n", mapInfo1)
fmt.Printf("获取到的map3是:%+v \n", mapInfo2)
}
// 关键转化代码
func Slice2Map(slice interface{}, keyName string) interface{} {
sliceType := reflect.TypeOf(slice)
if sliceType.Kind() != reflect.Slice {
return nil
}
valOf := reflect.ValueOf(slice)
length := valOf.Len()
if length == 0 {
return nil
}
// 获得map对应类型
mapT := reflect.MapOf(valOf.Index(0).FieldByName(keyName).Type(), valOf.Index(0).Type())
mapV := reflect.MakeMap(mapT)
for i := 0; i < length; i ++ {
structType := reflect.TypeOf(valOf.Index(i))
if structType.Kind() != reflect.Struct {
return nil
}
//mapV[struOf.FieldByName(keyName)] = struOf
mapV.SetMapIndex(valOf.Index(i).FieldByName(keyName), valOf.Index(i))
}
return mapV
}
我执行完的效果:
通过反射获取到slice中关键字段的属性 和 struct的属性,之后初始化map给map加入slice的值,这样就完成了,map的key 对应的val都是随着slice动态改变的。喜欢的话点个赞哦 ,谢啦~