github.com/m4gshm/gollections@v0.0.13-0.20240331203319-a34a86e58a24/collection/mutable/ordered/map.go (about)

     1  package ordered
     2  
     3  import (
     4  	"fmt"
     5  
     6  	breakLoop "github.com/m4gshm/gollections/break/kv/loop"
     7  	breakMapFilter "github.com/m4gshm/gollections/break/kv/predicate"
     8  	breakMapConvert "github.com/m4gshm/gollections/break/map_/convert"
     9  	"github.com/m4gshm/gollections/c"
    10  	"github.com/m4gshm/gollections/collection"
    11  	"github.com/m4gshm/gollections/collection/immutable/ordered"
    12  	"github.com/m4gshm/gollections/kv/convert"
    13  	"github.com/m4gshm/gollections/kv/loop"
    14  	filter "github.com/m4gshm/gollections/kv/predicate"
    15  	"github.com/m4gshm/gollections/map_"
    16  	"github.com/m4gshm/gollections/slice"
    17  )
    18  
    19  // WrapMap instantiates an ordered Map using a map and an order slice as internal storage
    20  func WrapMap[K comparable, V any](order []K, elements map[K]V) *Map[K, V] {
    21  	return &Map[K, V]{order: order, elements: elements}
    22  }
    23  
    24  // Map is a collection implementation that provides elements access by an unique key.
    25  type Map[K comparable, V any] struct {
    26  	order    []K
    27  	elements map[K]V
    28  }
    29  
    30  var (
    31  	_ c.Settable[int, any]                                        = (*Map[int, any])(nil)
    32  	_ c.SettableNew[int, any]                                     = (*Map[int, any])(nil)
    33  	_ c.SettableMap[c.TrackEach[int, any]]                        = (*Map[int, any])(nil)
    34  	_ c.ImmutableMapConvert[ordered.Map[int, any]]                = (*Map[int, any])(nil)
    35  	_ collection.Map[int, any]                                    = (*Map[int, any])(nil)
    36  	_ c.KeyVal[ordered.MapKeys[int], ordered.MapValues[int, any]] = (*Map[int, any])(nil)
    37  	_ fmt.Stringer                                                = (*Map[int, any])(nil)
    38  )
    39  
    40  // All is used to iterate through the collection using `for ... range`. Supported since go 1.22 with GOEXPERIMENT=rangefunc enabled.
    41  func (m *Map[K, V]) All(consumer func(K, V) bool) {
    42  	if m != nil {
    43  		map_.TrackOrderedWhile(m.order, m.elements, consumer)
    44  	}
    45  }
    46  
    47  // Loop creates a loop to iterate through the collection.
    48  func (m *Map[K, V]) Loop() loop.Loop[K, V] {
    49  	h := m.Head()
    50  	return h.Next
    51  }
    52  
    53  // Deprecated: Head is deprecated. Will be replaced by rance-over function iterator.
    54  // Head creates an iterator to iterate through the collection.
    55  func (m *Map[K, V]) Head() ordered.MapIter[K, V] {
    56  	var (
    57  		order    []K
    58  		elements map[K]V
    59  	)
    60  	if m != nil {
    61  		elements = m.elements
    62  		order = m.order
    63  	}
    64  	return ordered.NewMapIter(elements, slice.NewHead(order))
    65  }
    66  
    67  // Deprecated: Tail is deprecated. Will be replaced by rance-over function iterator.
    68  // Tail creates an iterator pointing to the end of the collection
    69  func (m *Map[K, V]) Tail() ordered.MapIter[K, V] {
    70  	var (
    71  		order    []K
    72  		elements map[K]V
    73  	)
    74  	if m != nil {
    75  		elements = m.elements
    76  		order = m.order
    77  	}
    78  	return ordered.NewMapIter(elements, slice.NewTail(order))
    79  }
    80  
    81  // Deprecated: First is deprecated. Will be replaced by rance-over function iterator.
    82  // First returns the first key/value pair of the map, an iterator to iterate over the remaining pair, and true\false marker of availability next pairs.
    83  // If no more then ok==false.
    84  func (m *Map[K, V]) First() (ordered.MapIter[K, V], K, V, bool) {
    85  	var (
    86  		iterator           = m.Head()
    87  		firstK, firstV, ok = iterator.Next()
    88  	)
    89  	return iterator, firstK, firstV, ok
    90  }
    91  
    92  // Map collects the key/value pairs to a map
    93  func (m *Map[K, V]) Map() map[K]V {
    94  	if m == nil {
    95  		return nil
    96  	}
    97  	return map_.Clone(m.elements)
    98  }
    99  
   100  // Sort sorts keys in-place (no copy)
   101  func (m *Map[K, V]) Sort(comparer slice.Comparer[K]) *Map[K, V] {
   102  	return m.sortBy(slice.Sort, comparer)
   103  }
   104  
   105  // StableSort sorts keys in-place (no copy)
   106  func (m *Map[K, V]) StableSort(comparer slice.Comparer[K]) *Map[K, V] {
   107  	return m.sortBy(slice.StableSort, comparer)
   108  }
   109  
   110  func (m *Map[K, V]) sortBy(sorter func([]K, slice.Comparer[K]) []K, comparer slice.Comparer[K]) *Map[K, V] {
   111  	if m != nil {
   112  		sorter(m.order, comparer)
   113  	}
   114  	return m
   115  }
   116  
   117  // Len returns the amount of elements contained in the map
   118  func (m *Map[K, V]) Len() int {
   119  	if m == nil {
   120  		return 0
   121  	}
   122  	return len(m.order)
   123  }
   124  
   125  // IsEmpty returns true if the map is empty
   126  func (m *Map[K, V]) IsEmpty() bool {
   127  	return m.Len() == 0
   128  }
   129  
   130  // Track applies the 'consumer' function for all key/value pairs until the consumer returns the c.Break to stop.
   131  func (m *Map[K, V]) Track(consumer func(K, V) error) error {
   132  	if m == nil {
   133  		return nil
   134  	}
   135  	return map_.TrackOrdered(m.order, m.elements, consumer)
   136  }
   137  
   138  // TrackEach applies the 'consumer' function for every key/value pairs
   139  func (m *Map[K, V]) TrackEach(consumer func(K, V)) {
   140  	if m == nil {
   141  		return
   142  	}
   143  	map_.TrackEachOrdered(m.order, m.elements, consumer)
   144  }
   145  
   146  // Contains checks is the map contains a key
   147  func (m *Map[K, V]) Contains(key K) bool {
   148  	if m == nil {
   149  		return false
   150  	}
   151  	_, ok := m.elements[key]
   152  	return ok
   153  }
   154  
   155  // Get returns the value for a key.
   156  // If ok==false, then the map does not contain the key.
   157  func (m *Map[K, V]) Get(key K) (V, bool) {
   158  	if m == nil {
   159  		var z V
   160  		return z, false
   161  	}
   162  	val, ok := m.elements[key]
   163  	return val, ok
   164  }
   165  
   166  // Set sets the value for a key
   167  func (m *Map[K, V]) Set(key K, value V) {
   168  	if m == nil {
   169  		return
   170  	}
   171  	u := m.elements
   172  	if u == nil {
   173  		u = map[K]V{}
   174  		m.elements = u
   175  	}
   176  	if _, ok := u[key]; !ok {
   177  		m.order = append(m.order, key)
   178  	}
   179  	u[key] = value
   180  }
   181  
   182  // SetNew sets the value fo a key only if the key is not exists in the map
   183  func (m *Map[K, V]) SetNew(key K, value V) bool {
   184  	if m == nil {
   185  		return false
   186  	}
   187  	u := m.elements
   188  	if u == nil {
   189  		u = map[K]V{}
   190  		m.elements = u
   191  	}
   192  
   193  	if _, ok := u[key]; !ok {
   194  		u[key] = value
   195  		m.order = append(m.order, key)
   196  		return true
   197  	}
   198  	return false
   199  }
   200  
   201  // Keys resutrns keys collection
   202  func (m *Map[K, V]) Keys() ordered.MapKeys[K] {
   203  	var order []K
   204  	if m != nil {
   205  		order = m.order
   206  	}
   207  	return ordered.WrapKeys(order)
   208  }
   209  
   210  // Values resutrns values collection
   211  func (m *Map[K, V]) Values() ordered.MapValues[K, V] {
   212  	var (
   213  		order    []K
   214  		elements map[K]V
   215  	)
   216  	if m != nil {
   217  		order, elements = m.order, m.elements
   218  	}
   219  	return ordered.WrapVal(order, elements)
   220  }
   221  
   222  // String string representation on the map
   223  func (m *Map[K, V]) String() string {
   224  	var (
   225  		order    []K
   226  		elements map[K]V
   227  	)
   228  	if m != nil {
   229  		order, elements = m.order, m.elements
   230  	}
   231  	return map_.ToStringOrdered(order, elements)
   232  }
   233  
   234  // FilterKey returns a loop consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
   235  func (m *Map[K, V]) FilterKey(predicate func(K) bool) loop.Loop[K, V] {
   236  	return loop.Filter(m.Loop(), filter.Key[V](predicate))
   237  }
   238  
   239  // FiltKey returns a loop consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
   240  func (m Map[K, V]) FiltKey(predicate func(K) (bool, error)) breakLoop.Loop[K, V] {
   241  	return loop.Filt(m.Loop(), breakMapFilter.Key[V](predicate))
   242  }
   243  
   244  // ConvertKey returns a loop that applies the 'converter' function to keys of the map
   245  func (m *Map[K, V]) ConvertKey(converter func(K) K) loop.Loop[K, V] {
   246  	return loop.Convert(m.Loop(), convert.Key[V](converter))
   247  }
   248  
   249  // ConvKey returns a loop that applies the 'converter' function to keys of the map
   250  func (m *Map[K, V]) ConvKey(converter func(K) (K, error)) breakLoop.Loop[K, V] {
   251  	return loop.Conv(m.Loop(), breakMapConvert.Key[V](converter))
   252  }
   253  
   254  // FilterValue returns a loop consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
   255  func (m *Map[K, V]) FilterValue(predicate func(V) bool) loop.Loop[K, V] {
   256  	return loop.Filter(m.Loop(), filter.Value[K](predicate))
   257  }
   258  
   259  // FiltValue returns a loop consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
   260  func (m *Map[K, V]) FiltValue(predicate func(V) (bool, error)) breakLoop.Loop[K, V] {
   261  	return loop.Filt(m.Loop(), breakMapFilter.Value[K](predicate))
   262  }
   263  
   264  // ConvertValue returns a loop that applies the 'converter' function to values of the map
   265  func (m *Map[K, V]) ConvertValue(converter func(V) V) loop.Loop[K, V] {
   266  	return loop.Convert(m.Loop(), convert.Value[K](converter))
   267  }
   268  
   269  // ConvValue returns a loop that applies the 'converter' function to values of the map
   270  func (m Map[K, V]) ConvValue(converter func(V) (V, error)) breakLoop.Loop[K, V] {
   271  	return loop.Conv(m.Loop(), breakMapConvert.Value[K](converter))
   272  }
   273  
   274  // Filter returns a loop consisting of elements that satisfy the condition of the 'predicate' function
   275  func (m *Map[K, V]) Filter(predicate func(K, V) bool) loop.Loop[K, V] {
   276  	return loop.Filter(m.Loop(), predicate)
   277  }
   278  
   279  // Filt returns a breakable loop consisting of elements that satisfy the condition of the 'predicate' function
   280  func (m *Map[K, V]) Filt(predicate func(K, V) (bool, error)) breakLoop.Loop[K, V] {
   281  	return loop.Filt(m.Loop(), predicate)
   282  }
   283  
   284  // Convert returns a loop that applies the 'converter' function to the collection elements
   285  func (m *Map[K, V]) Convert(converter func(K, V) (K, V)) loop.Loop[K, V] {
   286  	return loop.Convert(m.Loop(), converter)
   287  }
   288  
   289  // Conv returns a breakable loop that applies the 'converter' function to the collection elements
   290  func (m *Map[K, V]) Conv(converter func(K, V) (K, V, error)) breakLoop.Loop[K, V] {
   291  	return loop.Conv(m.Loop(), converter)
   292  }
   293  
   294  // Reduce reduces the key/value pairs of the map into an one pair using the 'merge' function
   295  func (m *Map[K, V]) Reduce(merge func(K, K, V, V) (K, V)) (k K, v V) {
   296  	if m != nil {
   297  		k, v = map_.Reduce(m.elements, merge)
   298  	}
   299  	return k, v
   300  }
   301  
   302  // HasAny finds the first key/value pair that satisfies the 'predicate' function condition and returns true if successful
   303  func (m *Map[K, V]) HasAny(predicate func(K, V) bool) bool {
   304  	return map_.HasAny(m.elements, predicate)
   305  }
   306  
   307  // Immutable converts to an immutable map instance
   308  func (m *Map[K, V]) Immutable() ordered.Map[K, V] {
   309  	var e map[K]V
   310  	var o []K
   311  	if m != nil {
   312  		e = map_.Clone(m.elements)
   313  		o = slice.Clone(m.order)
   314  	}
   315  	return ordered.WrapMap(o, e)
   316  }
   317  
   318  // SetMap inserts all elements from the 'other' map
   319  func (m *Map[K, V]) SetMap(kvs c.TrackEach[K, V]) {
   320  	if m == nil || kvs == nil {
   321  		return
   322  	}
   323  	kvs.TrackEach(func(key K, value V) { m.Set(key, value) })
   324  }
   325  
   326  func addToMap[K comparable, V any](key K, val V, order []K, uniques map[K]V) []K {
   327  	if _, ok := uniques[key]; !ok {
   328  		order = append(order, key)
   329  		uniques[key] = val
   330  	}
   331  	return order
   332  }