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  }