github.com/m4gshm/gollections@v0.0.13-0.20240331203319-a34a86e58a24/collection/immutable/vector.go (about) 1 package immutable 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/notsafe" 10 "github.com/m4gshm/gollections/slice" 11 ) 12 13 // WrapVector instantiates Vector using a slise as internal storage. 14 func WrapVector[T any](elements []T) Vector[T] { 15 return Vector[T]{elements: elements} 16 } 17 18 // Vector is a collection implementation that provides elements order and index access. 19 type Vector[T any] struct { 20 elements []T 21 } 22 23 var ( 24 _ collection.Vector[any] = (*Vector[any])(nil) 25 _ collection.Vector[any] = Vector[any]{} 26 _ fmt.Stringer = (*Vector[any])(nil) 27 _ fmt.Stringer = Vector[any]{} 28 ) 29 30 // All is used to iterate through the collection using `for ... range`. Supported since go 1.22 with GOEXPERIMENT=rangefunc enabled. 31 func (v Vector[T]) All(consumer func(int, T) bool) { 32 slice.TrackWhile(v.elements, consumer) 33 } 34 35 // Loop creates a loop to iterate through the collection. 36 func (v Vector[T]) Loop() loop.Loop[T] { 37 return loop.Of(v.elements...) 38 } 39 40 // Deprecated: Head is deprecated. Will be replaced by rance-over function iterator. 41 // Head creates an iterator to iterate through the collection. 42 func (v Vector[T]) Head() slice.Iter[T] { 43 return slice.NewHead(v.elements) 44 } 45 46 // Deprecated: Tail is deprecated. Will be replaced by rance-over function iterator. 47 // Tail creates an iterator pointing to the end of the collection 48 func (v Vector[T]) Tail() slice.Iter[T] { 49 return slice.NewTail(v.elements) 50 } 51 52 // Deprecated: First is deprecated. Will be replaced by rance-over function iterator. 53 // First returns the first element of the collection, an iterator to iterate over the remaining elements, and true\false marker of availability next elements. 54 // If no more elements then ok==false. 55 func (v Vector[T]) First() (*slice.Iter[T], T, bool) { 56 h := slice.NewHead(v.elements) 57 return h.Crank() 58 } 59 60 // Last returns the latest element of the collection, an iterator to reverse iterate over the remaining elements, and true\false marker of availability previous elements. 61 // If no more elements then ok==false. 62 func (v Vector[T]) Last() (*slice.Iter[T], T, bool) { 63 t := slice.NewTail(v.elements) 64 return t.CrankPrev() 65 } 66 67 // Slice collects the elements to a slice 68 func (v Vector[T]) Slice() []T { 69 if elements := v.elements; elements != nil { 70 return slice.Clone(elements) 71 } 72 return nil 73 } 74 75 // Append collects the values to the specified 'out' slice 76 func (v Vector[T]) Append(out []T) []T { 77 if elements := v.elements; elements != nil { 78 return append(out, elements...) 79 } 80 return out 81 } 82 83 // Len returns amount of elements 84 func (v Vector[T]) Len() int { 85 return notsafe.GetLen(v.elements) 86 } 87 88 // IsEmpty returns true if the collection is empty 89 func (v Vector[T]) IsEmpty() bool { 90 return v.Len() == 0 91 } 92 93 // Get returns an element by the index, otherwise, if the provided index is ouf of the vector len, returns zero T and false in the second result 94 func (v Vector[T]) Get(index int) (out T, ok bool) { 95 return slice.Gett(v.elements, index) 96 } 97 98 // Track applies the 'consumer' function for elements until the consumer returns the c.Break to stop. 99 func (v Vector[T]) Track(consumer func(int, T) error) error { 100 return slice.Track(v.elements, consumer) 101 } 102 103 // TrackEach applies the 'consumer' function for every key/value pairs 104 func (v Vector[T]) TrackEach(consumer func(int, T)) { 105 slice.TrackEach(v.elements, consumer) 106 } 107 108 // For applies the 'consumer' function for the elements until the consumer returns the c.Break to stop. 109 func (v Vector[T]) For(consumer func(T) error) error { 110 return slice.For(v.elements, consumer) 111 } 112 113 // ForEach applies the 'consumer' function for every element 114 func (v Vector[T]) ForEach(consumer func(T)) { 115 slice.ForEach(v.elements, consumer) 116 } 117 118 // Filter returns a loop consisting of elements that satisfy the condition of the 'predicate' function 119 func (v Vector[T]) Filter(filter func(T) bool) loop.Loop[T] { 120 return loop.Filter(v.Loop(), filter) 121 } 122 123 // Filt returns a breakable loop consisting of elements that satisfy the condition of the 'predicate' function 124 func (v Vector[T]) Filt(predicate func(T) (bool, error)) breakLoop.Loop[T] { 125 return loop.Filt(v.Loop(), predicate) 126 } 127 128 // Convert returns a loop that applies the 'converter' function to the collection elements 129 func (v Vector[T]) Convert(converter func(T) T) loop.Loop[T] { 130 return loop.Convert(v.Loop(), converter) 131 } 132 133 // Conv returns a breakable loop that applies the 'converter' function to the collection elements 134 func (v Vector[T]) Conv(converter func(T) (T, error)) breakLoop.Loop[T] { 135 return loop.Conv(v.Loop(), converter) 136 } 137 138 // Reduce reduces the elements into an one using the 'merge' function 139 func (v Vector[T]) Reduce(merge func(T, T) T) T { 140 return slice.Reduce(v.elements, merge) 141 } 142 143 // HasAny finds the first element that satisfies the 'predicate' function condition and returns true if successful 144 func (v Vector[T]) HasAny(predicate func(T) bool) bool { 145 return slice.HasAny(v.elements, predicate) 146 } 147 148 // Sort returns a sorted clone of the Vector 149 func (v Vector[T]) Sort(comparer slice.Comparer[T]) Vector[T] { 150 return v.sortBy(slice.Sort, comparer) 151 } 152 153 // StableSort returns a stable sorted clone of the Vector 154 func (v Vector[T]) StableSort(comparer slice.Comparer[T]) Vector[T] { 155 return v.sortBy(slice.StableSort, comparer) 156 } 157 158 func (v Vector[T]) sortBy(sorter func([]T, slice.Comparer[T]) []T, comparer slice.Comparer[T]) Vector[T] { 159 return WrapVector(sorter(slice.Clone(v.elements), comparer)) 160 } 161 162 func (v Vector[T]) String() string { 163 return slice.ToString(v.elements) 164 }