github.com/zlyuancn/zstr@v0.0.0-20230412074414-14d6b645962f/values_to_map.go (about) 1 /* 2 ------------------------------------------------- 3 Author : Zhang Fan 4 date: 2020/7/17 5 Description : 6 ------------------------------------------------- 7 */ 8 9 package zstr 10 11 import ( 12 "reflect" 13 "strconv" 14 ) 15 16 // 结构体值在渲染时读取的标签, 否则用字段名 17 const structValueTag = `render` 18 19 // 构建map, 支持 map[string]string,map[string]interface{}, KV, KVs 20 // 其它值按顺序转为 map[string]interface{}{"*[0]": 值0, "*[1]", 值1...} 21 func MakeMapOfValues(values ...interface{}) map[string]interface{} { 22 return makeMapOfValues(values) 23 } 24 25 // 构建map, 支持 map[string]string,map[string]interface{}, KV, KVs 26 // 其它值按顺序转为 map[string]interface{}{"*[0]": 值0, "*[1]", 值1...} 27 func makeMapOfValues(values []interface{}) map[string]interface{} { 28 if len(values) == 0 { 29 return make(map[string]interface{}) 30 } 31 32 // 注意, nil也是一个有效的值 33 34 if len(values) == 1 { 35 // map, kvs 36 switch v := values[0].(type) { 37 case map[string]interface{}: 38 return v 39 case KVs: 40 data := make(map[string]interface{}, len(v)) 41 for _, kv := range v { 42 data[kv.K] = kv.V 43 } 44 return data 45 } 46 47 // 其他类型 48 rv := reflect.Indirect(reflect.ValueOf(values[0])) 49 switch rv.Kind() { 50 case reflect.Map: 51 data := make(map[string]interface{}, rv.Len()) 52 for iter := rv.MapRange(); iter.Next(); { 53 data[anyToString(iter.Key().Interface())] = iter.Value().Interface() 54 } 55 return data 56 case reflect.Struct: 57 aType := rv.Type() 58 fieldCount := aType.NumField() 59 data := make(map[string]interface{}, fieldCount) 60 for i := 0; i < fieldCount; i++ { 61 field := aType.Field(i) 62 if field.PkgPath != "" { 63 continue 64 } 65 key := field.Tag.Get(structValueTag) 66 if key == "" { 67 key = field.Name 68 } 69 data[key] = rv.Field(i).Interface() 70 } 71 return data 72 } 73 74 } 75 76 // map, kvs 77 switch values[0].(type) { 78 case KV, *KV, KVs: 79 data := make(map[string]interface{}, len(values)) 80 for _, value := range values { 81 if kv, ok := value.(KV); ok { 82 data[kv.K] = kv.V 83 continue 84 } 85 if kv, ok := value.(*KV); ok { 86 data[kv.K] = kv.V 87 continue 88 } 89 if kvs, ok := value.(KVs); ok { 90 for _, kv := range kvs { 91 data[kv.K] = kv.V 92 } 93 continue 94 } 95 96 panic("所有值必须都是 zstr.KV 或者 *zstr.KV 或者 zstr.KVs") 97 } 98 return data 99 } 100 101 // values 102 data := make(map[string]interface{}, len(values)) 103 for i, v := range values { 104 data[`*[`+strconv.Itoa(i)+`]`] = v 105 } 106 return data 107 }