github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/ztype/map.go (about) 1 package ztype 2 3 import ( 4 "errors" 5 "reflect" 6 "strings" 7 "unsafe" 8 9 "github.com/sohaha/zlsgo/zreflect" 10 "github.com/sohaha/zlsgo/zstring" 11 ) 12 13 var ( 14 tagName = "z" 15 tagNameLesser = "json" 16 ) 17 18 type Map map[string]interface{} 19 20 func (m Map) DeepCopy() Map { 21 newMap := make(Map, len(m)) 22 for k := range m { 23 switch v := m[k].(type) { 24 case Map: 25 if v == nil { 26 newMap[k] = v 27 continue 28 } 29 newMap[k] = v.DeepCopy() 30 case map[string]interface{}: 31 newMap[k] = Map(v).DeepCopy() 32 default: 33 newMap[k] = v 34 } 35 } 36 37 return newMap 38 } 39 40 func (m Map) Get(key string, disabled ...bool) Type { 41 typ := Type{} 42 var ( 43 v interface{} 44 ok bool 45 ) 46 if len(disabled) > 0 && disabled[0] { 47 v, ok = m[key] 48 } else { 49 v, ok = parsePath(key, m) 50 } 51 if ok { 52 typ.v = v 53 } 54 return typ 55 } 56 57 func (m Map) Set(key string, value interface{}) error { 58 if m == nil { 59 return errors.New("map is nil") 60 } 61 62 m[key] = value 63 64 return nil 65 } 66 67 func (m Map) Has(key string) bool { 68 _, ok := m[key] 69 70 return ok 71 } 72 73 func (m Map) Delete(key string) error { 74 if _, ok := m[key]; ok { 75 delete(m, key) 76 return nil 77 } 78 79 return errors.New("key not found") 80 } 81 82 func (m Map) ForEach(fn func(k string, v Type) bool) { 83 for s, v := range m { 84 if !fn(s, Type{v}) { 85 return 86 } 87 } 88 } 89 90 func (m Map) IsEmpty() bool { 91 return len(m) == 0 92 } 93 94 type Maps []Map 95 96 func (m Maps) IsEmpty() bool { 97 return len(m) == 0 98 } 99 100 func (m Maps) Len() int { 101 return len(m) 102 } 103 104 func (m Maps) Index(i int) Map { 105 if i < 0 || i >= len(m) { 106 return Map{} 107 } 108 return m[i] 109 } 110 111 func (m Maps) Last() Map { 112 l := m.Len() 113 if l == 0 { 114 return Map{} 115 } 116 return m[l-1] 117 } 118 119 func (m Maps) First() Map { 120 return m.Index(0) 121 } 122 123 func (m Maps) ForEach(fn func(i int, value Map) bool) { 124 for i := range m { 125 v := m[i] 126 if !fn(i, v) { 127 break 128 } 129 } 130 } 131 132 // MapKeyExists Whether the dictionary key exists 133 func MapKeyExists(key interface{}, m map[interface{}]interface{}) bool { 134 _, ok := m[key] 135 return ok 136 } 137 138 func ToMap(value interface{}) Map { 139 switch v := value.(type) { 140 case Map: 141 return v 142 case map[string]interface{}: 143 return v 144 default: 145 return toMapString(v) 146 } 147 } 148 149 // ToMaps to Slice Map 150 func ToMaps(value interface{}) Maps { 151 switch r := value.(type) { 152 case Maps: 153 return r 154 case []map[string]interface{}: 155 return *(*Maps)(unsafe.Pointer(&r)) 156 default: 157 ref := reflect.Indirect(zreflect.ValueOf(value)) 158 m := make(Maps, 0) 159 l := ref.Len() 160 v := ref.Slice(0, l) 161 for i := 0; i < l; i++ { 162 m = append(m, toMapString(v.Index(i).Interface())) 163 } 164 return m 165 } 166 } 167 168 func toMapString(value interface{}) map[string]interface{} { 169 if value == nil { 170 return map[string]interface{}{} 171 } 172 if r, ok := value.(map[string]interface{}); ok { 173 return r 174 } 175 m := map[string]interface{}{} 176 switch val := value.(type) { 177 case map[interface{}]interface{}: 178 for k, v := range val { 179 m[ToString(k)] = v 180 } 181 case map[interface{}]string: 182 for k, v := range val { 183 m[ToString(k)] = v 184 } 185 case map[interface{}]int: 186 for k, v := range val { 187 m[ToString(k)] = v 188 } 189 case map[interface{}]uint: 190 for k, v := range val { 191 m[ToString(k)] = v 192 } 193 case map[interface{}]float64: 194 for k, v := range val { 195 m[ToString(k)] = v 196 } 197 case map[string]bool: 198 for k, v := range val { 199 m[k] = v 200 } 201 case map[string]int: 202 for k, v := range val { 203 m[k] = v 204 } 205 case map[string]uint: 206 for k, v := range val { 207 m[k] = v 208 } 209 case map[string]float64: 210 for k, v := range val { 211 m[k] = v 212 } 213 case map[int]interface{}: 214 for k, v := range val { 215 m[ToString(k)] = v 216 } 217 case map[int]string: 218 for k, v := range val { 219 m[ToString(k)] = v 220 } 221 case map[uint]string: 222 for k, v := range val { 223 m[ToString(k)] = v 224 } 225 default: 226 toMapStringReflect(&m, value) 227 } 228 return m 229 } 230 231 func toMapStringReflect(m *map[string]interface{}, val interface{}) { 232 rv := zreflect.ValueOf(val) 233 kind := rv.Kind() 234 if kind == reflect.Ptr { 235 rv = rv.Elem() 236 kind = rv.Kind() 237 } 238 switch kind { 239 case reflect.Map: 240 ks := rv.MapKeys() 241 for _, k := range ks { 242 (*m)[ToString(k.Interface())] = rv.MapIndex(k).Interface() 243 } 244 case reflect.Struct: 245 rt := rv.Type() 246 ol: 247 for i := 0; i < rv.NumField(); i++ { 248 field := rt.Field(i) 249 fieldName := field.Name 250 if !zstring.IsUcfirst(fieldName) { 251 continue 252 } 253 254 name, opt := zreflect.GetStructTag(field, tagName, tagNameLesser) 255 if name == "" { 256 continue 257 } 258 array := strings.Split(opt, ",") 259 v := rv.Field(i) 260 for i := range array { 261 switch strings.TrimSpace(array[i]) { 262 case "omitempty": 263 if IsEmpty(v.Interface()) { 264 continue ol 265 } 266 } 267 } 268 fv := reflect.Indirect(v) 269 switch fv.Kind() { 270 case reflect.Struct: 271 (*m)[name] = toMapString(v.Interface()) 272 continue 273 case reflect.Slice: 274 if field.Type.Elem().Kind() == reflect.Struct { 275 mc := make([]map[string]interface{}, v.Len()) 276 for i := 0; i < v.Len(); i++ { 277 mc[i] = toMapString(v.Index(i).Interface()) 278 } 279 (*m)[name] = mc 280 continue 281 } 282 } 283 (*m)[name] = v.Interface() 284 } 285 default: 286 (*m)["0"] = val 287 } 288 }