github.com/yaoapp/kun@v0.9.0/maps/stranysync.go (about)

     1  package maps
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"reflect"
     7  	"sort"
     8  	"sync"
     9  
    10  	"github.com/yaoapp/kun/interfaces"
    11  )
    12  
    13  // MapSync alias of MapStrAnySync
    14  type MapSync = MapStrAnySync
    15  
    16  // MapStrSync alias of MapStrAnySync
    17  type MapStrSync = MapStrAnySync
    18  
    19  // StrSync alias of MapStrAnySync
    20  type StrSync = MapStrAnySync
    21  
    22  // StrAnySync alias of MapStrAnySync
    23  type StrAnySync = MapStrAnySync
    24  
    25  // MapStrAnySync type of sync.Map
    26  type MapStrAnySync struct {
    27  	*sync.Map
    28  }
    29  
    30  // MakeSync create a new instance
    31  func MakeSync() MapStrAnySync {
    32  	return MakeMapStrAnySync()
    33  }
    34  
    35  // MakeMapSync create a new instance
    36  func MakeMapSync() MapStrAnySync {
    37  	return MakeMapStrAnySync()
    38  }
    39  
    40  // MakeMapStrSync create a new instance
    41  func MakeMapStrSync() MapStrAnySync {
    42  	return MakeMapStrAnySync()
    43  }
    44  
    45  // MakeStrSync create a new instance
    46  func MakeStrSync() MapStrAnySync {
    47  	return MakeMapStrAnySync()
    48  }
    49  
    50  // MakeStrAnySync create a new instance
    51  func MakeStrAnySync() MapStrAnySync {
    52  	return MakeMapStrAnySync()
    53  }
    54  
    55  // MakeMapStrAnySync create a new instance
    56  func MakeMapStrAnySync() MapStrAnySync {
    57  	return MapStrAnySync{
    58  		Map: &sync.Map{},
    59  	}
    60  }
    61  
    62  // SyncOf create a new instance
    63  func SyncOf(data map[string]interface{}) MapStrAnySync {
    64  	return MapStrAnySyncOf(data)
    65  }
    66  
    67  // MapSyncOf create a new instance
    68  func MapSyncOf(data map[string]interface{}) MapStrAnySync {
    69  	return MapStrAnySyncOf(data)
    70  }
    71  
    72  // MapStrSyncOf create a new instance
    73  func MapStrSyncOf(data map[string]interface{}) MapStrAnySync {
    74  	return MapStrAnySyncOf(data)
    75  }
    76  
    77  // StrSyncOf create a new instance
    78  func StrSyncOf(data map[string]interface{}) MapStrAnySync {
    79  	return MapStrAnySyncOf(data)
    80  }
    81  
    82  // StrAnySyncOf create a new instance
    83  func StrAnySyncOf(data map[string]interface{}) MapStrAnySync {
    84  	return MapStrAnySyncOf(data)
    85  }
    86  
    87  // MapStrAnySyncOf create a new instance
    88  func MapStrAnySyncOf(data map[string]interface{}) MapStrAnySync {
    89  	m := MakeMapStrAnySync()
    90  	for key, value := range data {
    91  		m.Set(key, value)
    92  	}
    93  	return m
    94  }
    95  
    96  // Flatten The Flatten method is alias of Dot, to flatten a multi-dimensional map[string]inteface{} into a single level  map[string]inteface{}
    97  // that uses "dot" notation to indicate depth
    98  func (m MapStrAnySync) Flatten() MapStrAnySync {
    99  	return m.Dot()
   100  }
   101  
   102  // Dot The Dot method flattens a multi-dimensional map[string]inteface{} into a single level  map[string]inteface{}
   103  // that uses "dot" notation to indicate depth
   104  func (m MapStrAnySync) Dot() MapStrAnySync {
   105  	res := MakeMapStrAnySync()
   106  	m.Range(func(key string, value interface{}) bool {
   107  		res.dotSet(key, value)
   108  		return true
   109  	})
   110  	return res
   111  }
   112  
   113  // dotSet set the value for a key uses "dot" notation
   114  func (m MapStrAnySync) dotSet(key string, value interface{}) {
   115  
   116  	m.Set(key, value)
   117  
   118  	reflectValue := reflect.ValueOf(value)
   119  	reflectValue = reflect.Indirect(reflectValue)
   120  	valueKind := reflectValue.Kind()
   121  
   122  	if valueKind == reflect.Slice || valueKind == reflect.Array { // Slice || Array
   123  		for i := 0; i < reflectValue.Len(); i++ {
   124  			m.dotSet(fmt.Sprintf("%s.%d", key, i), reflectValue.Index(i).Interface())
   125  		}
   126  
   127  	} else if valueKind == reflect.Map { // Map
   128  		for _, sub := range reflectValue.MapKeys() {
   129  			m.dotSet(fmt.Sprintf("%s.%v", key, sub), reflectValue.MapIndex(sub).Interface())
   130  		}
   131  	}
   132  }
   133  
   134  // Set set the value for a key
   135  func (m MapStrAnySync) Set(key string, value interface{}) {
   136  	m.Store(key, value)
   137  }
   138  
   139  // Get get the value of the given key
   140  func (m MapStrAnySync) Get(key string) interface{} {
   141  	value, has := m.Load(key)
   142  	if has {
   143  		return value
   144  	}
   145  	return nil
   146  }
   147  
   148  // Has return true whether value was found in the map.
   149  func (m MapStrAnySync) Has(key string) bool {
   150  	_, has := m.Map.Load(key)
   151  	return has
   152  }
   153  
   154  // Del deletes the value for a key.
   155  func (m MapStrAnySync) Del(key string) {
   156  	m.Delete(key)
   157  }
   158  
   159  // GetOrSet returns the existing value for the key if present. Otherwise, it stores and returns the given value.
   160  func (m MapStrAnySync) GetOrSet(key string, value interface{}) interface{} {
   161  	value, load := m.LoadOrStore(key, value)
   162  	if load {
   163  		return value
   164  	}
   165  
   166  	return value
   167  }
   168  
   169  // GetAndDel deletes the value for a key, returning the previous value if any. The loaded result reports whether the key was present.
   170  func (m MapStrAnySync) GetAndDel(key string) interface{} {
   171  	value := m.Get(key)
   172  	m.Del(key)
   173  	return value
   174  }
   175  
   176  // Len returns the length of the map.
   177  func (m MapStrAnySync) Len() int {
   178  	length := 0
   179  	m.Map.Range(func(key, value interface{}) bool {
   180  		length++
   181  		return true
   182  	})
   183  	return length
   184  }
   185  
   186  // Range calls f sequentially for each key and value present in the map. If f returns false, range stops the iteration.
   187  func (m MapStrAnySync) Range(cb func(key string, value interface{}) bool) {
   188  	m.Map.Range(func(key, value interface{}) bool {
   189  		keyStr := key.(string)
   190  		return cb(keyStr, value)
   191  	})
   192  }
   193  
   194  // Keys returns all keys of the map as a slice.
   195  func (m MapStrAnySync) Keys() []string {
   196  	keys := []string{}
   197  	m.Range(func(key string, value interface{}) bool {
   198  		keys = append(keys, key)
   199  		return true
   200  	})
   201  	sort.Strings(keys)
   202  	return keys
   203  }
   204  
   205  // Values returns all values of the map as a slice.
   206  func (m MapStrAnySync) Values() []interface{} {
   207  	values := []interface{}{}
   208  	keys := m.Keys()
   209  	for _, key := range keys {
   210  		values = append(values, m.Get(key))
   211  	}
   212  	return values
   213  }
   214  
   215  //IsEmpty checks whether the map is empty. It returns true if map is empty, or else false.
   216  func (m MapStrAnySync) IsEmpty() bool {
   217  	empty := true
   218  	m.Range(func(key string, value interface{}) bool {
   219  		empty = false
   220  		return false
   221  	})
   222  	return empty
   223  }
   224  
   225  // Merge merges hash maps
   226  func (m MapStrAnySync) Merge(maps ...interfaces.MapStrAny) {
   227  	for _, new := range maps {
   228  		new.Range(func(key string, value interface{}) bool {
   229  			m.Set(key, value)
   230  			return true
   231  		})
   232  	}
   233  }
   234  
   235  // MarshalJSON for json marshalJSON
   236  func (m MapStrAnySync) MarshalJSON() ([]byte, error) {
   237  	res := map[string]interface{}{}
   238  	m.Range(func(key string, value interface{}) bool {
   239  		res[key] = value
   240  		return true
   241  	})
   242  	return json.Marshal(res)
   243  }