github.com/yaoapp/kun@v0.9.0/any/map.go (about) 1 package any 2 3 import ( 4 "fmt" 5 "reflect" 6 7 "github.com/yaoapp/kun/maps" 8 "github.com/yaoapp/kun/share" 9 ) 10 11 // Map the replacement for Maps.Map 12 type Map struct { 13 maps.MapStrAny 14 } 15 16 // MakeMap create a new map instance 17 func MakeMap() Map { 18 return Map{MapStrAny: maps.MapStrAnyOf(map[string]interface{}{})} 19 } 20 21 // MapOf create a new map instance 22 func MapOf(values interface{}) Map { 23 if values == nil { 24 return MakeMap() 25 } 26 switch values.(type) { 27 case map[string]interface{}: 28 return Map{MapStrAny: maps.MapStrAnyOf(values.(map[string]interface{}))} 29 } 30 31 // converts to map 32 reflectValues := reflect.ValueOf(values) 33 reflectValues = reflect.Indirect(reflectValues) 34 if reflectValues.Kind() == reflect.Map { 35 valuesMap := map[string]interface{}{} 36 for _, key := range reflectValues.MapKeys() { 37 k := fmt.Sprintf("%v", key) 38 valuesMap[k] = reflectValues.MapIndex(key).Interface() 39 } 40 return Map{MapStrAny: maps.MapStrAnyOf(valuesMap)} 41 } else if reflectValues.Kind() == reflect.Struct { 42 valuesMap := map[string]interface{}{} 43 typeOfS := reflectValues.Type() 44 for i := 0; i < reflectValues.NumField(); i++ { 45 name := share.GetTagName(typeOfS.Field(i), "json") 46 valuesMap[name] = reflectValues.Field(i).Interface() 47 } 48 return Map{MapStrAny: maps.MapStrAnyOf(valuesMap)} 49 } 50 51 panic(fmt.Sprintf("v is %s not a type of map", reflectValues.Kind())) 52 } 53 54 // Any returns the value stored in the map for a key. 55 func (m Map) Any(key string) *Any { 56 return Of(m.Get(key)) 57 } 58 59 // Flatten The Flatten method is alias of Dot, to flatten a multi-dimensional map[string]inteface{} into a single level map[string]inteface{} 60 // that uses "dot" notation to indicate depth 61 func (m Map) Flatten() Map { 62 return m.Dot() 63 } 64 65 // Dot The Dot method flattens a multi-dimensional map[string]inteface{} into a single level map[string]inteface{} 66 // that uses "dot" notation to indicate depth 67 func (m Map) Dot() Map { 68 res := MakeMap() 69 m.Range(func(key string, value interface{}) bool { 70 res.dotSet(key, value) 71 return true 72 }) 73 return res 74 } 75 76 // dotSet set the value for a key uses "dot" notation 77 func (m Map) dotSet(key string, value interface{}) { 78 79 m.Set(key, value) 80 81 reflectValue := reflect.ValueOf(value) 82 reflectValue = reflect.Indirect(reflectValue) 83 valueKind := reflectValue.Kind() 84 85 if valueKind == reflect.Slice || valueKind == reflect.Array { // Slice || Array 86 for i := 0; i < reflectValue.Len(); i++ { 87 m.dotSet(fmt.Sprintf("%s.%d", key, i), reflectValue.Index(i).Interface()) 88 } 89 90 } else if valueKind == reflect.Map { // Map 91 for _, sub := range reflectValue.MapKeys() { 92 m.dotSet(fmt.Sprintf("%s.%v", key, sub), reflectValue.MapIndex(sub).Interface()) 93 } 94 } 95 }