github.com/m4gshm/gollections@v0.0.10/collection/mutable/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  	breakKvStream "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/collection/immutable/ordered"
    14  	"github.com/m4gshm/gollections/kv"
    15  	"github.com/m4gshm/gollections/kv/loop"
    16  	"github.com/m4gshm/gollections/kv/stream"
    17  	"github.com/m4gshm/gollections/map_"
    18  	"github.com/m4gshm/gollections/map_/convert"
    19  	"github.com/m4gshm/gollections/map_/filter"
    20  	"github.com/m4gshm/gollections/notsafe"
    21  	"github.com/m4gshm/gollections/slice"
    22  )
    23  
    24  // WrapMap instantiates an ordered Map using a map and an order slice as internal storage
    25  func WrapMap[K comparable, V any](order []K, elements map[K]V) *Map[K, V] {
    26  	return &Map[K, V]{order: order, elements: elements, ksize: notsafe.GetTypeSize[K]()}
    27  }
    28  
    29  // Map is a collection implementation that provides elements access by an unique key.
    30  type Map[K comparable, V any] struct {
    31  	order      []K
    32  	elements   map[K]V
    33  	changeMark int32
    34  	ksize      uintptr
    35  }
    36  
    37  var (
    38  	_ c.Settable[int, any]                                        = (*Map[int, any])(nil)
    39  	_ c.SettableNew[int, any]                                     = (*Map[int, any])(nil)
    40  	_ c.SettableMap[c.TrackEachLoop[int, any]]                    = (*Map[int, any])(nil)
    41  	_ c.ImmutableMapConvert[ordered.Map[int, any]]                = (*Map[int, any])(nil)
    42  	_ collection.Map[int, any]                                    = (*Map[int, any])(nil)
    43  	_ loop.Looper[int, any, *ordered.MapIter[int, any]]           = (*Map[int, any])(nil)
    44  	_ c.KeyVal[ordered.MapKeys[int], ordered.MapValues[int, any]] = (*Map[int, any])(nil)
    45  	_ fmt.Stringer                                                = (*Map[int, any])(nil)
    46  )
    47  
    48  // Iter creates an iterator and returns as interface
    49  func (m *Map[K, V]) Iter() kv.Iterator[K, V] {
    50  	h := m.Head()
    51  	return &h
    52  }
    53  
    54  // Loop creates an iterator and returns as implementation type reference
    55  func (m *Map[K, V]) Loop() *ordered.MapIter[K, V] {
    56  	h := m.Head()
    57  	return &h
    58  }
    59  
    60  // Head creates an iterator and returns as implementation type value
    61  func (m *Map[K, V]) Head() ordered.MapIter[K, V] {
    62  	var (
    63  		order    []K
    64  		elements map[K]V
    65  		ksize    uintptr
    66  	)
    67  	if m != nil {
    68  		elements = m.elements
    69  		order = m.order
    70  		ksize = m.ksize
    71  	}
    72  	return ordered.NewMapIter(elements, slice.NewHeadS(order, ksize))
    73  }
    74  
    75  // Tail creates an iterator pointing to the end of the collection
    76  func (m *Map[K, V]) Tail() ordered.MapIter[K, V] {
    77  	var (
    78  		order    []K
    79  		elements map[K]V
    80  		ksize    uintptr
    81  	)
    82  	if m != nil {
    83  		elements = m.elements
    84  		order = m.order
    85  		ksize = m.ksize
    86  	}
    87  	return ordered.NewMapIter(elements, slice.NewTailS(order, ksize))
    88  }
    89  
    90  // 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.
    91  // If no more then ok==false.
    92  func (m *Map[K, V]) First() (ordered.MapIter[K, V], K, V, bool) {
    93  	var (
    94  		iterator           = m.Head()
    95  		firstK, firstV, ok = iterator.Next()
    96  	)
    97  	return iterator, firstK, firstV, ok
    98  }
    99  
   100  // Map collects the key/value pairs to a map
   101  func (m *Map[K, V]) Map() map[K]V {
   102  	if m == nil {
   103  		return nil
   104  	}
   105  	return map_.Clone(m.elements)
   106  }
   107  
   108  // Sort transforms to the ordered Map contains sorted elements
   109  func (m *Map[K, V]) Sort(less slice.Less[K]) *Map[K, V] {
   110  	return m.sortBy(sort.Slice, less)
   111  }
   112  
   113  // StableSort transforms to the ordered Map contains sorted elements
   114  func (m *Map[K, V]) StableSort(less slice.Less[K]) *Map[K, V] {
   115  	return m.sortBy(sort.SliceStable, less)
   116  }
   117  
   118  func (m *Map[K, V]) sortBy(sorter slice.Sorter, less slice.Less[K]) *Map[K, V] {
   119  	if m != nil {
   120  		slice.Sort(m.order, sorter, less)
   121  	}
   122  	return m
   123  }
   124  
   125  // Len returns the amount of elements contained in the map
   126  func (m *Map[K, V]) Len() int {
   127  	if m == nil {
   128  		return 0
   129  	}
   130  	return len(m.order)
   131  }
   132  
   133  // IsEmpty returns true if the map is empty
   134  func (m *Map[K, V]) IsEmpty() bool {
   135  	return m.Len() == 0
   136  }
   137  
   138  // For applies the 'walker' function for key/value pairs. Return the c.ErrBreak to stop.
   139  func (m *Map[K, V]) For(walker func(c.KV[K, V]) error) error {
   140  	if m == nil {
   141  		return nil
   142  	}
   143  	return map_.ForOrdered(m.order, m.elements, walker)
   144  }
   145  
   146  // ForEach applies the 'walker' function for every key/value pair
   147  func (m *Map[K, V]) ForEach(walker func(c.KV[K, V])) {
   148  	if m == nil {
   149  		return
   150  	}
   151  	map_.ForEachOrdered(m.order, m.elements, walker)
   152  }
   153  
   154  // Track applies the 'tracker' function for key/value pairs. Return the c.ErrBreak to stop.
   155  func (m *Map[K, V]) Track(tracker func(K, V) error) error {
   156  	if m == nil {
   157  		return nil
   158  	}
   159  	return map_.TrackOrdered(m.order, m.elements, tracker)
   160  }
   161  
   162  // TrackEach applies the 'tracker' function for every key/value pairs
   163  func (m *Map[K, V]) TrackEach(tracker func(K, V)) {
   164  	if m == nil {
   165  		return
   166  	}
   167  	map_.TrackEachOrdered(m.order, m.elements, tracker)
   168  }
   169  
   170  // Contains checks is the map contains a key
   171  func (m *Map[K, V]) Contains(key K) bool {
   172  	if m == nil {
   173  		return false
   174  	}
   175  	_, ok := m.elements[key]
   176  	return ok
   177  }
   178  
   179  // Get returns the value for a key.
   180  // If ok==false, then the map does not contain the key.
   181  func (m *Map[K, V]) Get(key K) (V, bool) {
   182  	if m == nil {
   183  		var z V
   184  		return z, false
   185  	}
   186  	val, ok := m.elements[key]
   187  	return val, ok
   188  }
   189  
   190  // Set sets the value for a key
   191  func (m *Map[K, V]) Set(key K, value V) {
   192  	if m == nil {
   193  		return
   194  	}
   195  	u := m.elements
   196  	if u == nil {
   197  		u = map[K]V{}
   198  		m.elements = u
   199  	}
   200  	if _, ok := u[key]; !ok {
   201  		m.order = append(m.order, key)
   202  	}
   203  	u[key] = value
   204  }
   205  
   206  // SetNew sets the value fo a key only if the key is not exists in the map
   207  func (m *Map[K, V]) SetNew(key K, value V) bool {
   208  	if m == nil {
   209  		return false
   210  	}
   211  	u := m.elements
   212  	if u == nil {
   213  		u = map[K]V{}
   214  		m.elements = u
   215  	}
   216  
   217  	if _, ok := u[key]; !ok {
   218  		u[key] = value
   219  		m.order = append(m.order, key)
   220  		return true
   221  	}
   222  	return false
   223  }
   224  
   225  // Keys resutrns keys collection
   226  func (m *Map[K, V]) Keys() ordered.MapKeys[K] {
   227  	var order []K
   228  	if m != nil {
   229  		order = m.order
   230  	}
   231  	return ordered.WrapKeys(order)
   232  }
   233  
   234  // Values resutrns values collection
   235  func (m *Map[K, V]) Values() ordered.MapValues[K, V] {
   236  	var (
   237  		order    []K
   238  		elements map[K]V
   239  	)
   240  	if m != nil {
   241  		order, elements = m.order, m.elements
   242  	}
   243  	return ordered.WrapVal(order, elements)
   244  }
   245  
   246  // String string representation on the map
   247  func (m *Map[K, V]) String() string {
   248  	var (
   249  		order    []K
   250  		elements map[K]V
   251  	)
   252  	if m != nil {
   253  		order, elements = m.order, m.elements
   254  	}
   255  	return map_.ToStringOrdered(order, elements)
   256  }
   257  
   258  // FilterKey returns a stream consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
   259  func (m *Map[K, V]) FilterKey(predicate func(K) bool) stream.Iter[K, V, map[K]V] {
   260  	h := m.Head()
   261  	return stream.New(loop.Filter(h.Next, filter.Key[V](predicate)).Next, loop.ToMap[K, V])
   262  }
   263  
   264  // FiltKey returns a stream consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
   265  func (m Map[K, V]) FiltKey(predicate func(K) (bool, error)) breakKvStream.Iter[K, V, map[K]V] {
   266  	h := m.Head()
   267  	return breakKvStream.New(breakLoop.Filt(breakLoop.From(h.Next), breakMapFilter.Key[V](predicate)).Next, breakLoop.ToMap[K, V])
   268  }
   269  
   270  // ConvertKey returns a stream that applies the 'converter' function to keys of the map
   271  func (m *Map[K, V]) ConvertKey(converter func(K) K) stream.Iter[K, V, map[K]V] {
   272  	h := m.Head()
   273  	return stream.New(loop.Convert(h.Next, convert.Key[V](converter)).Next, loop.ToMap[K, V])
   274  }
   275  
   276  // ConvKey returns a stream that applies the 'converter' function to keys of the map
   277  func (m *Map[K, V]) ConvKey(converter func(K) (K, error)) breakKvStream.Iter[K, V, map[K]V] {
   278  	h := m.Head()
   279  	return breakKvStream.New(breakLoop.Conv(breakLoop.From(h.Next), breakMapConvert.Key[V](converter)).Next, breakLoop.ToMap[K, V])
   280  }
   281  
   282  // FilterValue returns a stream consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
   283  func (m *Map[K, V]) FilterValue(predicate func(V) bool) stream.Iter[K, V, map[K]V] {
   284  	h := m.Head()
   285  	return stream.New(loop.Filter(h.Next, filter.Value[K](predicate)).Next, loop.ToMap[K, V])
   286  }
   287  
   288  // FiltValue returns a stream consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
   289  func (m *Map[K, V]) FiltValue(predicate func(V) (bool, error)) breakKvStream.Iter[K, V, map[K]V] {
   290  	h := m.Head()
   291  	return breakKvStream.New(breakLoop.Filt(breakLoop.From(h.Next), breakMapFilter.Value[K](predicate)).Next, breakLoop.ToMap[K, V])
   292  }
   293  
   294  // ConvertValue returns a stream that applies the 'converter' function to values of the map
   295  func (m *Map[K, V]) ConvertValue(converter func(V) V) stream.Iter[K, V, map[K]V] {
   296  	h := m.Head()
   297  	return stream.New(loop.Convert(h.Next, convert.Value[K](converter)).Next, loop.ToMap[K, V])
   298  }
   299  
   300  // ConvValue returns a stream that applies the 'converter' function to values of the map
   301  func (m Map[K, V]) ConvValue(converter func(V) (V, error)) breakKvStream.Iter[K, V, map[K]V] {
   302  	h := m.Head()
   303  	return breakKvStream.New(breakLoop.Conv(breakLoop.From(h.Next), breakMapConvert.Value[K](converter)).Next, breakLoop.ToMap[K, V])
   304  }
   305  
   306  // Filter returns a stream consisting of elements that satisfy the condition of the 'predicate' function
   307  func (m *Map[K, V]) Filter(predicate func(K, V) bool) stream.Iter[K, V, map[K]V] {
   308  	h := m.Head()
   309  	return stream.New(loop.Filter(h.Next, predicate).Next, loop.ToMap[K, V])
   310  }
   311  
   312  // Filt returns a breakable stream consisting of elements that satisfy the condition of the 'predicate' function
   313  func (m *Map[K, V]) Filt(predicate func(K, V) (bool, error)) breakKvStream.Iter[K, V, map[K]V] {
   314  	h := m.Head()
   315  	return breakKvStream.New(breakLoop.Filt(breakLoop.From(h.Next), predicate).Next, breakLoop.ToMap[K, V])
   316  }
   317  
   318  // Convert returns a stream that applies the 'converter' function to the collection elements
   319  func (m *Map[K, V]) Convert(converter func(K, V) (K, V)) stream.Iter[K, V, map[K]V] {
   320  	h := m.Head()
   321  	return stream.New(loop.Convert(h.Next, converter).Next, loop.ToMap[K, V])
   322  }
   323  
   324  // Conv returns a breakable stream that applies the 'converter' function to the collection elements
   325  func (m *Map[K, V]) Conv(converter func(K, V) (K, V, error)) breakKvStream.Iter[K, V, map[K]V] {
   326  	h := m.Head()
   327  	return breakKvStream.New(breakLoop.Conv(breakLoop.From(h.Next), converter).Next, breakLoop.ToMap[K, V])
   328  }
   329  
   330  // Reduce reduces the key/value pairs of the map into an one pair using the 'merge' function
   331  func (m *Map[K, V]) Reduce(merge func(K, K, V, V) (K, V)) (k K, v V) {
   332  	if m != nil {
   333  		k, v = map_.Reduce(m.elements, merge)
   334  	}
   335  	return k, v
   336  }
   337  
   338  // HasAny finds the first key/value pair that satisfies the 'predicate' function condition and returns true if successful
   339  func (m *Map[K, V]) HasAny(predicate func(K, V) bool) bool {
   340  	return map_.HasAny(m.elements, predicate)
   341  }
   342  
   343  // Immutable converts to an immutable map instance
   344  func (m *Map[K, V]) Immutable() ordered.Map[K, V] {
   345  	var e map[K]V
   346  	var o []K
   347  	if m != nil {
   348  		e = map_.Clone(m.elements)
   349  		o = slice.Clone(m.order)
   350  	}
   351  	return ordered.WrapMap(o, e)
   352  }
   353  
   354  // SetMap inserts all elements from the 'other' map
   355  func (m *Map[K, V]) SetMap(kvs c.TrackEachLoop[K, V]) {
   356  	if m == nil || kvs == nil {
   357  		return
   358  	}
   359  	kvs.TrackEach(func(key K, value V) { m.Set(key, value) })
   360  }
   361  
   362  func addToMap[K comparable, V any](key K, val V, order []K, uniques map[K]V) []K {
   363  	if _, ok := uniques[key]; !ok {
   364  		order = append(order, key)
   365  		uniques[key] = val
   366  	}
   367  	return order
   368  }