github.com/m4gshm/gollections@v0.0.10/collection/immutable/ordered/map.go (about)

     1  package ordered
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  
     7  	breakLoop "github.com/m4gshm/gollections/break/kv/loop"
     8  	kvstream "github.com/m4gshm/gollections/break/kv/stream"
     9  	breakMapConvert "github.com/m4gshm/gollections/break/map_/convert"
    10  	breakMapFilter "github.com/m4gshm/gollections/break/map_/filter"
    11  	"github.com/m4gshm/gollections/c"
    12  	"github.com/m4gshm/gollections/collection"
    13  	"github.com/m4gshm/gollections/kv"
    14  	"github.com/m4gshm/gollections/kv/loop"
    15  	"github.com/m4gshm/gollections/kv/stream"
    16  	"github.com/m4gshm/gollections/map_"
    17  	"github.com/m4gshm/gollections/map_/convert"
    18  	"github.com/m4gshm/gollections/map_/filter"
    19  	"github.com/m4gshm/gollections/notsafe"
    20  	"github.com/m4gshm/gollections/slice"
    21  )
    22  
    23  // WrapMap instantiates ordered Map using a map and an order slice as internal storage.
    24  func WrapMap[K comparable, V any](order []K, elements map[K]V) Map[K, V] {
    25  	return Map[K, V]{order: order, elements: elements, ksize: notsafe.GetTypeSize[K]()}
    26  }
    27  
    28  // Map is a collection implementation that provides elements access by an unique key.
    29  type Map[K comparable, V any] struct {
    30  	order    []K
    31  	elements map[K]V
    32  	ksize    uintptr
    33  }
    34  
    35  var (
    36  	_ collection.Map[int, any]                    = (*Map[int, any])(nil)
    37  	_ collection.Map[int, any]                    = Map[int, any]{}
    38  	_ loop.Looper[int, any, *MapIter[int, any]]   = (*Map[int, any])(nil)
    39  	_ loop.Looper[int, any, *MapIter[int, any]]   = Map[int, any]{}
    40  	_ c.KeyVal[MapKeys[int], MapValues[int, any]] = (*Map[int, any])(nil)
    41  	_ c.KeyVal[MapKeys[int], MapValues[int, any]] = Map[int, any]{}
    42  	_ fmt.Stringer                                = (*Map[int, any])(nil)
    43  	_ fmt.Stringer                                = Map[int, any]{}
    44  )
    45  
    46  // Iter creates an iterator and returns as interface
    47  func (m Map[K, V]) Iter() kv.Iterator[K, V] {
    48  	h := m.Head()
    49  	return &h
    50  }
    51  
    52  // Loop creates an iterator and returns as implementation type reference
    53  func (m Map[K, V]) Loop() *MapIter[K, V] {
    54  	h := m.Head()
    55  	return &h
    56  }
    57  
    58  // Head creates an iterator and returns as implementation type value
    59  func (m Map[K, V]) Head() MapIter[K, V] {
    60  	return NewMapIter(m.elements, slice.NewHeadS(m.order, m.ksize))
    61  }
    62  
    63  // 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.
    64  // If no more then ok==false.
    65  func (m Map[K, V]) First() (MapIter[K, V], K, V, bool) {
    66  	var (
    67  		iterator           = m.Head()
    68  		firstK, firstV, ok = iterator.Next()
    69  	)
    70  	return iterator, firstK, firstV, ok
    71  }
    72  
    73  // Tail creates an iterator pointing to the end of the map
    74  func (m Map[K, V]) Tail() MapIter[K, V] {
    75  	return NewMapIter(m.elements, slice.NewTailS(m.order, m.ksize))
    76  }
    77  
    78  // Map collects the key/value pairs to a map
    79  func (m Map[K, V]) Map() map[K]V {
    80  	return map_.Clone(m.elements)
    81  }
    82  
    83  // Len returns amount of elements
    84  func (m Map[K, V]) Len() int {
    85  	return len(m.order)
    86  }
    87  
    88  // IsEmpty returns true if the map is empty
    89  func (m Map[K, V]) IsEmpty() bool {
    90  	return m.Len() == 0
    91  }
    92  
    93  // Contains checks is the map contains a key
    94  func (m Map[K, V]) Contains(key K) (ok bool) {
    95  	if m.elements != nil {
    96  		_, ok = m.elements[key]
    97  	}
    98  	return ok
    99  }
   100  
   101  // Get returns the value for a key.
   102  // If ok==false, then the map does not contain the key.
   103  func (m Map[K, V]) Get(key K) (element V, ok bool) {
   104  	if m.elements != nil {
   105  		element, ok = m.elements[key]
   106  	}
   107  	return element, ok
   108  }
   109  
   110  // Keys resutrns keys collection
   111  func (m Map[K, V]) Keys() MapKeys[K] {
   112  	return WrapKeys(m.order)
   113  }
   114  
   115  // Values resutrns values collection
   116  func (m Map[K, V]) Values() MapValues[K, V] {
   117  	return WrapVal(m.order, m.elements)
   118  }
   119  
   120  // Sort sorts the elements
   121  func (m Map[K, V]) Sort(less slice.Less[K]) Map[K, V] {
   122  	return m.sortBy(sort.Slice, less)
   123  }
   124  
   125  // StableSort sorts the elements
   126  func (m Map[K, V]) StableSort(less slice.Less[K]) Map[K, V] {
   127  	return m.sortBy(sort.SliceStable, less)
   128  }
   129  
   130  func (m Map[K, V]) sortBy(sorter slice.Sorter, less slice.Less[K]) Map[K, V] {
   131  	order := slice.Clone(m.order)
   132  	slice.Sort(order, sorter, less)
   133  	return WrapMap(order, m.elements)
   134  }
   135  
   136  func (m Map[K, V]) String() string {
   137  	return map_.ToStringOrdered(m.order, m.elements)
   138  }
   139  
   140  // Track applies the 'tracker' function for key/value pairs. Return the c.ErrBreak to stop.
   141  func (m Map[K, V]) Track(tracker func(K, V) error) error {
   142  	return map_.TrackOrdered(m.order, m.elements, tracker)
   143  }
   144  
   145  // TrackEach applies the 'tracker' function for every key/value pairs
   146  func (m Map[K, V]) TrackEach(tracker func(K, V)) {
   147  	map_.TrackEachOrdered(m.order, m.elements, tracker)
   148  }
   149  
   150  // For applies the 'walker' function for key/value pairs. Return the c.ErrBreak to stop.
   151  func (m Map[K, V]) For(walker func(c.KV[K, V]) error) error {
   152  	return map_.ForOrdered(m.order, m.elements, walker)
   153  }
   154  
   155  // ForEach applies the 'walker' function for every key/value pair
   156  func (m Map[K, V]) ForEach(walker func(c.KV[K, V])) {
   157  	map_.ForEachOrdered(m.order, m.elements, walker)
   158  }
   159  
   160  // FilterKey returns a stream consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
   161  func (m Map[K, V]) FilterKey(predicate func(K) bool) stream.Iter[K, V, map[K]V] {
   162  	h := m.Head()
   163  	return stream.New(loop.Filter(h.Next, filter.Key[V](predicate)).Next, loop.ToMap[K, V])
   164  }
   165  
   166  // FiltKey returns a stream consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
   167  func (m Map[K, V]) FiltKey(predicate func(K) (bool, error)) kvstream.Iter[K, V, map[K]V] {
   168  	h := m.Head()
   169  	return kvstream.New(breakLoop.Filt(breakLoop.From(h.Next), breakMapFilter.Key[V](predicate)).Next, breakLoop.ToMap[K, V])
   170  }
   171  
   172  // ConvertKey returns a stream that applies the 'converter' function to keys of the map
   173  func (m Map[K, V]) ConvertKey(by func(K) K) stream.Iter[K, V, map[K]V] {
   174  	h := m.Head()
   175  	return stream.New(loop.Convert(h.Next, convert.Key[V](by)).Next, loop.ToMap[K, V])
   176  }
   177  
   178  // ConvKey returns a stream that applies the 'converter' function to keys of the map
   179  func (m Map[K, V]) ConvKey(converter func(K) (K, error)) kvstream.Iter[K, V, map[K]V] {
   180  	h := m.Head()
   181  	return kvstream.New(breakLoop.Conv(breakLoop.From(h.Next), breakMapConvert.Key[V](converter)).Next, breakLoop.ToMap[K, V])
   182  }
   183  
   184  // FilterValue returns a stream consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
   185  func (m Map[K, V]) FilterValue(predicate func(V) bool) stream.Iter[K, V, map[K]V] {
   186  	h := m.Head()
   187  	return stream.New(loop.Filter(h.Next, filter.Value[K](predicate)).Next, loop.ToMap[K, V])
   188  }
   189  
   190  // FiltValue returns a breakable stream consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
   191  func (m Map[K, V]) FiltValue(predicate func(V) (bool, error)) kvstream.Iter[K, V, map[K]V] {
   192  	h := m.Head()
   193  	return kvstream.New(breakLoop.Filt(breakLoop.From(h.Next), breakMapFilter.Value[K](predicate)).Next, breakLoop.ToMap[K, V])
   194  }
   195  
   196  // ConvertValue returns a stream that applies the 'converter' function to values of the map
   197  func (m Map[K, V]) ConvertValue(converter func(V) V) stream.Iter[K, V, map[K]V] {
   198  	h := m.Head()
   199  	return stream.New(loop.Convert(h.Next, convert.Value[K](converter)).Next, loop.ToMap[K, V])
   200  }
   201  
   202  // ConvValue returns a breakable stream that applies the 'converter' function to values of the map
   203  func (m Map[K, V]) ConvValue(converter func(V) (V, error)) kvstream.Iter[K, V, map[K]V] {
   204  	h := m.Head()
   205  	return kvstream.New(breakLoop.Conv(breakLoop.From(h.Next), breakMapConvert.Value[K](converter)).Next, breakLoop.ToMap[K, V])
   206  }
   207  
   208  // Filter returns a stream consisting of elements that satisfy the condition of the 'predicate' function
   209  func (m Map[K, V]) Filter(predicate func(K, V) bool) stream.Iter[K, V, map[K]V] {
   210  	h := m.Head()
   211  	return stream.New(loop.Filter(h.Next, predicate).Next, loop.ToMap[K, V])
   212  }
   213  
   214  // Filt returns a breakable stream consisting of elements that satisfy the condition of the 'predicate' function
   215  func (m Map[K, V]) Filt(predicate func(K, V) (bool, error)) kvstream.Iter[K, V, map[K]V] {
   216  	h := m.Head()
   217  	return kvstream.New(breakLoop.Filt(breakLoop.From(h.Next), predicate).Next, breakLoop.ToMap[K, V])
   218  }
   219  
   220  // Convert returns a stream that applies the 'converter' function to the collection elements
   221  func (m Map[K, V]) Convert(converter func(K, V) (K, V)) stream.Iter[K, V, map[K]V] {
   222  	h := m.Head()
   223  	return stream.New(loop.Convert(h.Next, converter).Next, loop.ToMap[K, V])
   224  }
   225  
   226  // Conv returns a breakable stream that applies the 'converter' function to the collection elements
   227  func (m Map[K, V]) Conv(converter func(K, V) (K, V, error)) kvstream.Iter[K, V, map[K]V] {
   228  	h := m.Head()
   229  	return kvstream.New(breakLoop.Conv(breakLoop.From(h.Next), converter).Next, breakLoop.ToMap[K, V])
   230  }
   231  
   232  // Reduce reduces the key/value pairs of the map into an one pair using the 'merge' function
   233  func (m Map[K, V]) Reduce(merge func(K, K, V, V) (K, V)) (K, V) {
   234  	return map_.Reduce(m.elements, merge)
   235  }
   236  
   237  // HasAny finds the first key/value pair that satisfies the 'predicate' function condition and returns true if successful
   238  func (m Map[K, V]) HasAny(predicate func(K, V) bool) bool {
   239  	return map_.HasAny(m.elements, predicate)
   240  }
   241  
   242  func addToMap[K comparable, V any](key K, val V, order []K, uniques map[K]V) []K {
   243  	if _, ok := uniques[key]; !ok {
   244  		order = append(order, key)
   245  		uniques[key] = val
   246  	}
   247  	return order
   248  }