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

     1  package immutable
     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 Map using a map as internal storage.
    20  func WrapMap[K comparable, V any](elements map[K]V) Map[K, V] {
    21  	return Map[K, V]{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  	elements map[K]V
    27  }
    28  
    29  var (
    30  	_ collection.Map[int, any]                         = (*Map[int, any])(nil)
    31  	_ collection.Map[int, any]                         = Map[int, any]{}
    32  	_ c.KeyVal[MapKeys[int, any], MapValues[int, any]] = (*Map[int, any])(nil)
    33  	_ c.KeyVal[MapKeys[int, any], MapValues[int, any]] = Map[int, any]{}
    34  	_ fmt.Stringer                                     = (*Map[int, any])(nil)
    35  	_ fmt.Stringer                                     = Map[int, any]{}
    36  )
    37  
    38  // All is used to iterate through the collection using `for ... range`. Supported since go 1.22 with GOEXPERIMENT=rangefunc enabled.
    39  func (m Map[K, V]) All(consumer func(k K, v V) bool) {
    40  	for k, v := range m.elements {
    41  		if !consumer(k, v) {
    42  			break
    43  		}
    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() map_.Iter[K, V] {
    56  	return map_.NewIter(m.elements)
    57  }
    58  
    59  // Deprecated: First is deprecated. Will be replaced by rance-over function iterator.
    60  // 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.
    61  // If no more then ok==false.
    62  func (m Map[K, V]) First() (map_.Iter[K, V], K, V, bool) {
    63  	var (
    64  		iterator           = m.Head()
    65  		firstK, firstV, ok = iterator.Next()
    66  	)
    67  	return iterator, firstK, firstV, ok
    68  }
    69  
    70  // Map collects the key/value pairs to a map
    71  func (m Map[K, V]) Map() map[K]V {
    72  	return map_.Clone(m.elements)
    73  }
    74  
    75  // Len returns amount of elements
    76  func (m Map[K, V]) Len() int {
    77  	return len(m.elements)
    78  }
    79  
    80  // IsEmpty returns true if the map is empty
    81  func (m Map[K, V]) IsEmpty() bool {
    82  	return m.Len() == 0
    83  }
    84  
    85  // Contains checks is the map contains a key
    86  func (m Map[K, V]) Contains(key K) (ok bool) {
    87  	if m.elements != nil {
    88  		_, ok = m.elements[key]
    89  	}
    90  	return ok
    91  }
    92  
    93  // Get returns the value for a key.
    94  // If ok==false, then the map does not contain the key.
    95  func (m Map[K, V]) Get(key K) (element V, ok bool) {
    96  	if m.elements != nil {
    97  		element, ok = m.elements[key]
    98  	}
    99  	return element, ok
   100  }
   101  
   102  // Keys resutrns keys collection
   103  func (m Map[K, V]) Keys() MapKeys[K, V] {
   104  	return m.K()
   105  }
   106  
   107  // K resutrns keys collection impl
   108  func (m Map[K, V]) K() MapKeys[K, V] {
   109  	return WrapKeys(m.elements)
   110  }
   111  
   112  // Values resutrns values collection
   113  func (m Map[K, V]) Values() MapValues[K, V] {
   114  	return m.V()
   115  }
   116  
   117  // V resutrns values collection impl
   118  func (m Map[K, V]) V() MapValues[K, V] {
   119  	return WrapVal(m.elements)
   120  }
   121  
   122  // Sort returns sorted by keys map
   123  func (m Map[K, V]) Sort(comparer slice.Comparer[K]) ordered.Map[K, V] {
   124  	return m.sortBy(slice.Sort, comparer)
   125  }
   126  
   127  // StableSort returns sorted by keys map
   128  func (m Map[K, V]) StableSort(comparer slice.Comparer[K]) ordered.Map[K, V] {
   129  	return m.sortBy(slice.StableSort, comparer)
   130  }
   131  
   132  func (m Map[K, V]) sortBy(sorter func([]K, slice.Comparer[K]) []K, comparer slice.Comparer[K]) ordered.Map[K, V] {
   133  	return ordered.WrapMap(sorter(map_.Keys(m.elements), comparer), m.elements)
   134  }
   135  
   136  func (m Map[K, V]) String() string {
   137  	return map_.ToString(m.elements)
   138  }
   139  
   140  // Track applies the 'consumer' function for all key/value pairs until the consumer returns the c.Break to stop.
   141  func (m Map[K, V]) Track(consumer func(K, V) error) error {
   142  	return map_.Track(m.elements, consumer)
   143  }
   144  
   145  // TrackEach applies the 'consumer' function for every key/value pairs
   146  func (m Map[K, V]) TrackEach(consumer func(K, V)) {
   147  	map_.TrackEach(m.elements, consumer)
   148  }
   149  
   150  // FilterKey returns a loop consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
   151  func (m Map[K, V]) FilterKey(predicate func(K) bool) loop.Loop[K, V] {
   152  	return loop.Filter(m.Loop(), filter.Key[V](predicate))
   153  }
   154  
   155  // FiltKey returns a loop consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
   156  func (m Map[K, V]) FiltKey(predicate func(K) (bool, error)) breakLoop.Loop[K, V] {
   157  	return loop.Filt(m.Loop(), breakMapFilter.Key[V](predicate))
   158  }
   159  
   160  // ConvertKey returns a loop that applies the 'converter' function to keys of the map
   161  func (m Map[K, V]) ConvertKey(by func(K) K) loop.Loop[K, V] {
   162  	return loop.Convert(m.Loop(), convert.Key[V](by))
   163  }
   164  
   165  // ConvKey returns a loop that applies the 'converter' function to keys of the map
   166  func (m Map[K, V]) ConvKey(converter func(K) (K, error)) breakLoop.Loop[K, V] {
   167  	return loop.Conv(m.Loop(), breakMapConvert.Key[V](converter))
   168  }
   169  
   170  // FilterValue returns a loop consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
   171  func (m Map[K, V]) FilterValue(predicate func(V) bool) loop.Loop[K, V] {
   172  	return loop.Filter(m.Loop(), filter.Value[K](predicate))
   173  }
   174  
   175  // FiltValue returns a loop consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
   176  func (m Map[K, V]) FiltValue(predicate func(V) (bool, error)) breakLoop.Loop[K, V] {
   177  	return loop.Filt(m.Loop(), breakMapFilter.Value[K](predicate))
   178  }
   179  
   180  // ConvertValue returns a loop that applies the 'converter' function to values of the map
   181  func (m Map[K, V]) ConvertValue(by func(V) V) loop.Loop[K, V] {
   182  	return loop.Convert(m.Loop(), convert.Value[K](by))
   183  }
   184  
   185  // ConvValue returns a loop that applies the 'converter' function to values of the map
   186  func (m Map[K, V]) ConvValue(converter func(V) (V, error)) breakLoop.Loop[K, V] {
   187  	return loop.Conv(m.Loop(), breakMapConvert.Value[K](converter))
   188  }
   189  
   190  // Filter returns a loop consisting of elements that satisfy the condition of the 'predicate' function
   191  func (m Map[K, V]) Filter(predicate func(K, V) bool) loop.Loop[K, V] {
   192  	return loop.Filter(m.Loop(), predicate)
   193  }
   194  
   195  // Filt returns a breakable loop consisting of elements that satisfy the condition of the 'predicate' function
   196  func (m Map[K, V]) Filt(predicate func(K, V) (bool, error)) breakLoop.Loop[K, V] {
   197  	return loop.Filt(m.Loop(), predicate)
   198  }
   199  
   200  // Convert returns a loop that applies the 'converter' function to the collection elements
   201  func (m Map[K, V]) Convert(converter func(K, V) (K, V)) loop.Loop[K, V] {
   202  	return loop.Convert(m.Loop(), converter)
   203  }
   204  
   205  // Conv returns a breakable loop that applies the 'converter' function to the collection elements
   206  func (m Map[K, V]) Conv(converter func(K, V) (K, V, error)) breakLoop.Loop[K, V] {
   207  	return loop.Conv(m.Loop(), converter)
   208  }
   209  
   210  // Reduce reduces the key/value pairs of the map into an one pair using the 'merge' function
   211  func (m Map[K, V]) Reduce(merge func(K, K, V, V) (K, V)) (K, V) {
   212  	return map_.Reduce(m.elements, merge)
   213  }
   214  
   215  // HasAny finds the first key/value pair that satisfies the 'predicate' function condition and returns true if successful
   216  func (m Map[K, V]) HasAny(predicate func(K, V) bool) bool {
   217  	return map_.HasAny(m.elements, predicate)
   218  }