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

     1  package ordered
     2  
     3  import (
     4  	"fmt"
     5  
     6  	breakLoop "github.com/m4gshm/gollections/break/loop"
     7  	"github.com/m4gshm/gollections/collection"
     8  	"github.com/m4gshm/gollections/loop"
     9  	"github.com/m4gshm/gollections/map_"
    10  	"github.com/m4gshm/gollections/slice"
    11  )
    12  
    13  // WrapVal instantiates MapValues using elements as internal storage.
    14  func WrapVal[K comparable, V any](order []K, elements map[K]V) MapValues[K, V] {
    15  	return MapValues[K, V]{order, elements}
    16  }
    17  
    18  // MapValues is the wrapper for Map'm values.
    19  type MapValues[K comparable, V any] struct {
    20  	order    []K
    21  	elements map[K]V
    22  }
    23  
    24  var (
    25  	_ collection.Collection[any] = (*MapValues[int, any])(nil)
    26  	_ fmt.Stringer               = (*MapValues[int, any])(nil)
    27  )
    28  
    29  // Loop creates a loop to iterate through the collection.
    30  func (m MapValues[K, V]) Loop() loop.Loop[V] {
    31  	h := m.Head()
    32  	return h.Next
    33  }
    34  
    35  // Deprecated: Head is deprecated. Will be replaced by rance-over function iterator.
    36  // Head creates an iterator to iterate through the collection.
    37  func (m MapValues[K, V]) Head() *ValIter[K, V] {
    38  	var (
    39  		order    []K
    40  		elements map[K]V
    41  	)
    42  
    43  	order = m.order
    44  	elements = m.elements
    45  
    46  	return NewValIter(order, elements)
    47  }
    48  
    49  // Deprecated: First is deprecated. Will be replaced by rance-over function iterator.
    50  // First returns the first element of the collection, an iterator to iterate over the remaining elements, and true\false marker of availability next elements.
    51  // If no more elements then ok==false.
    52  func (m MapValues[K, V]) First() (*ValIter[K, V], V, bool) {
    53  	var (
    54  		iterator  = m.Head()
    55  		first, ok = iterator.Next()
    56  	)
    57  	return iterator, first, ok
    58  }
    59  
    60  // Len returns amount of elements
    61  func (m MapValues[K, V]) Len() int {
    62  	return len(m.elements)
    63  }
    64  
    65  // IsEmpty returns true if the collection is empty
    66  func (m MapValues[K, V]) IsEmpty() bool {
    67  	return m.Len() == 0
    68  }
    69  
    70  // Slice collects the values to a slice
    71  func (m MapValues[K, V]) Slice() (values []V) {
    72  	return m.Append(values)
    73  }
    74  
    75  // Append collects the values to the specified 'out' slice
    76  func (m MapValues[K, V]) Append(out []V) (values []V) {
    77  	for _, key := range m.order {
    78  		val := m.elements[key]
    79  		out = append(out, val)
    80  	}
    81  	return out
    82  }
    83  
    84  // All is used to iterate through the collection using `for ... range`. Supported since go 1.22 with GOEXPERIMENT=rangefunc enabled.
    85  func (m MapValues[K, V]) All(consumer func(V) bool) {
    86  	map_.TrackOrderedValuesWhile(m.order, m.elements, consumer)
    87  }
    88  
    89  // For applies the 'consumer' function for every value until the consumer returns the c.Break to stop.
    90  func (m MapValues[K, V]) For(consumer func(V) error) error {
    91  	return map_.ForOrderedValues(m.order, m.elements, consumer)
    92  }
    93  
    94  // ForEach applies the 'consumer' function for every value
    95  func (m MapValues[K, V]) ForEach(consumer func(V)) {
    96  	map_.ForEachOrderedValues(m.order, m.elements, consumer)
    97  }
    98  
    99  // Get returns an element by the index, otherwise, if the provided index is ouf of the collection len, returns zero T and false in the second result
   100  func (m MapValues[K, V]) Get(index int) (V, bool) {
   101  	keys := m.order
   102  	if index >= 0 && index < len(keys) {
   103  		key := keys[index]
   104  		val, ok := m.elements[key]
   105  		return val, ok
   106  	}
   107  	var no V
   108  	return no, false
   109  }
   110  
   111  // Filter returns a loop consisting of elements that satisfy the condition of the 'predicate' function
   112  func (m MapValues[K, V]) Filter(filter func(V) bool) loop.Loop[V] {
   113  	return loop.Filter(m.Loop(), filter)
   114  }
   115  
   116  // Filt returns a breakable loop consisting of elements that satisfy the condition of the 'predicate' function
   117  func (m MapValues[K, V]) Filt(filter func(V) (bool, error)) breakLoop.Loop[V] {
   118  	return loop.Filt(m.Loop(), filter)
   119  }
   120  
   121  // Convert returns a loop that applies the 'converter' function to the collection elements
   122  func (m MapValues[K, V]) Convert(converter func(V) V) loop.Loop[V] {
   123  	return loop.Convert(m.Loop(), converter)
   124  }
   125  
   126  // Conv returns a breakable loop that applies the 'converter' function to the collection elements
   127  func (m MapValues[K, V]) Conv(converter func(V) (V, error)) breakLoop.Loop[V] {
   128  	return loop.Conv(m.Loop(), converter)
   129  }
   130  
   131  // Reduce reduces the elements into an one using the 'merge' function
   132  func (m MapValues[K, V]) Reduce(merge func(V, V) V) V {
   133  	_, v := map_.Reduce(m.elements, func(_, _ K, v1, v2 V) (k K, v V) {
   134  		return k, merge(v1, v2)
   135  	})
   136  	return v
   137  }
   138  
   139  // HasAny finds the first element that satisfies the 'predicate' function condition and returns true if successful
   140  func (m MapValues[K, V]) HasAny(predicate func(V) bool) bool {
   141  	return map_.HasAny(m.elements, func(_ K, v V) bool {
   142  		return predicate(v)
   143  	})
   144  }
   145  
   146  func (m MapValues[K, V]) String() string {
   147  	return slice.ToString(m.Slice())
   148  }