github.com/m4gshm/gollections@v0.0.13-0.20240331203319-a34a86e58a24/collection/mutable/vector.go (about) 1 package mutable 2 3 import ( 4 "fmt" 5 "sort" 6 7 breakLoop "github.com/m4gshm/gollections/break/loop" 8 "github.com/m4gshm/gollections/c" 9 "github.com/m4gshm/gollections/collection" 10 "github.com/m4gshm/gollections/loop" 11 "github.com/m4gshm/gollections/notsafe" 12 "github.com/m4gshm/gollections/slice" 13 ) 14 15 // WrapVector instantiates Vector using a slise as internal storage 16 func WrapVector[T any](elements []T) *Vector[T] { 17 v := Vector[T](elements) 18 return &v 19 } 20 21 // Vector is a collection implementation that provides elements order and index access 22 type Vector[T any] []T 23 24 var ( 25 _ c.Addable[any] = (*Vector[any])(nil) 26 _ c.AddableAll[c.ForEach[any]] = (*Vector[any])(nil) 27 _ c.Deleteable[int] = (*Vector[any])(nil) 28 _ c.DeleteableVerify[int] = (*Vector[any])(nil) 29 _ c.Settable[int, any] = (*Vector[any])(nil) 30 _ c.SettableNew[int, any] = (*Vector[any])(nil) 31 _ collection.Vector[any] = (*Vector[any])(nil) 32 _ fmt.Stringer = (*Vector[any])(nil) 33 ) 34 35 // All is used to iterate through the collection using `for ... range`. Supported since go 1.22 with GOEXPERIMENT=rangefunc enabled. 36 func (v *Vector[T]) All(consumer func(int, T) bool) { 37 if v != nil { 38 slice.TrackWhile(*v, consumer) 39 } 40 } 41 42 // Loop creates a loop to iterate through the collection. 43 func (v *Vector[T]) Loop() loop.Loop[T] { 44 if v == nil { 45 return nil 46 } 47 return loop.Of(*v...) 48 } 49 50 // Deprecated: Head is deprecated. Will be replaced by rance-over function iterator. 51 // Head creates an iterator to iterate through the collection. 52 func (v *Vector[T]) Head() *SliceIter[T] { 53 return NewHead(v, v.DeleteActualOne) 54 } 55 56 // Deprecated: Tail is deprecated. Will be replaced by rance-over function iterator. 57 // Tail creates an iterator pointing to the end of the collection 58 func (v *Vector[T]) Tail() *SliceIter[T] { 59 return NewTail(v, v.DeleteActualOne) 60 } 61 62 // Deprecated: First is deprecated. Will be replaced by rance-over function iterator. 63 // First returns the first element of the collection, an iterator to iterate over the remaining elements, and true\false marker of availability next elements. 64 // If no more elements then ok==false. 65 func (v *Vector[T]) First() (*SliceIter[T], T, bool) { 66 var ( 67 iterator = NewHead(v, v.DeleteActualOne) 68 first, ok = iterator.Next() 69 ) 70 return iterator, first, ok 71 } 72 73 // 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. 74 // If no more elements then ok==false. 75 func (v *Vector[T]) Last() (*SliceIter[T], T, bool) { 76 var ( 77 iterator = NewTail(v, v.DeleteActualOne) 78 first, ok = iterator.Prev() 79 ) 80 return iterator, first, ok 81 } 82 83 // Slice collects the elements to a slice 84 func (v *Vector[T]) Slice() (out []T) { 85 if v == nil { 86 return out 87 } 88 return slice.Clone(*v) 89 } 90 91 // Append collects the values to the specified 'out' slice 92 func (v *Vector[T]) Append(out []T) []T { 93 if v == nil { 94 return out 95 } 96 return append(out, (*v)...) 97 } 98 99 // Clone just makes a copy of the vector instance 100 func (v *Vector[T]) Clone() *Vector[T] { 101 return WrapVector(slice.Clone(*v)) 102 } 103 104 // IsEmpty returns true if the collection is empty 105 func (v *Vector[T]) IsEmpty() bool { 106 return v.Len() == 0 107 } 108 109 // Len returns amount of elements 110 func (v *Vector[T]) Len() int { 111 if v == nil { 112 return 0 113 } 114 return notsafe.GetLen(*v) 115 } 116 117 // Track applies consumer to elements with error checking until the consumer returns the c.Break to stop.tracking. 118 func (v *Vector[T]) Track(consumer func(int, T) error) error { 119 if v == nil { 120 return nil 121 } 122 return slice.Track(*v, consumer) 123 } 124 125 // TrackEach applies consumer to elements without error checking 126 func (v *Vector[T]) TrackEach(consumer func(int, T)) { 127 if v != nil { 128 slice.TrackEach(*v, consumer) 129 } 130 } 131 132 // For applies the 'consumer' function for the elements until the consumer returns the c.Break to stop. 133 func (v *Vector[T]) For(consumer func(T) error) error { 134 if v == nil { 135 return nil 136 } 137 return slice.For(*v, consumer) 138 } 139 140 // ForEach applies consumer to elements without error checking 141 func (v *Vector[T]) ForEach(consumer func(T)) { 142 if !(v == nil) { 143 slice.ForEach(*v, consumer) 144 } 145 } 146 147 // 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 148 func (v *Vector[T]) Get(index int) (t T, ok bool) { 149 if v == nil { 150 return 151 } 152 return slice.Gett(*v, index) 153 } 154 155 // Add adds elements to the end of the vector 156 func (v *Vector[T]) Add(elements ...T) { 157 if v != nil { 158 *v = append(*v, elements...) 159 } 160 } 161 162 // AddOne adds an element to the end of the vector 163 func (v *Vector[T]) AddOne(element T) { 164 if v != nil { 165 *v = append(*v, element) 166 } 167 } 168 169 // AddAll inserts all elements from the "other" collection 170 func (v *Vector[T]) AddAll(other c.ForEach[T]) { 171 if v != nil { 172 other.ForEach(func(element T) { *v = append(*v, element) }) 173 } 174 } 175 176 // DeleteOne removes an element by the index 177 func (v *Vector[T]) DeleteOne(index int) { 178 _ = v.DeleteActualOne(index) 179 } 180 181 // DeleteActualOne removes an element by the index 182 func (v *Vector[T]) DeleteActualOne(index int) bool { 183 _, ok := v.Remove(index) 184 return ok 185 } 186 187 // Remove removes and returns an element by the index 188 func (v *Vector[T]) Remove(index int) (t T, ok bool) { 189 if v == nil { 190 return t, ok 191 } 192 if e := *v; index >= 0 && index < len(e) { 193 de := e[index] 194 *v = slice.Delete(e, index) 195 return de, true 196 } 197 return t, ok 198 } 199 200 // Delete drops elements by indexes 201 func (v *Vector[T]) Delete(indexes ...int) { 202 v.DeleteActual(indexes...) 203 } 204 205 // DeleteActual drops elements by indexes with verification of no-op 206 func (v *Vector[T]) DeleteActual(indexes ...int) bool { 207 if v == nil { 208 return false 209 } 210 l := len(indexes) 211 if l == 0 { 212 return false 213 } else if l == 1 { 214 return v.DeleteActualOne(indexes[0]) 215 } 216 217 e := *v 218 el := len(e) 219 220 sort.Ints(indexes) 221 222 shift := 0 223 for i := 0; i < l; i++ { 224 index := indexes[i] - shift 225 delAmount := 1 226 if index >= 0 && index < el { 227 curIndex := index 228 for i < l-1 { 229 nextIndex := indexes[i+1] 230 if nextIndex-curIndex == 1 { 231 delAmount++ 232 i++ 233 curIndex = nextIndex 234 } else { 235 break 236 } 237 } 238 239 e = append(e[0:index], e[index+delAmount:]...) 240 shift += delAmount 241 } 242 } 243 if shift > 0 { 244 *v = e 245 return true 246 } 247 return false 248 } 249 250 // Set puts an element into the vector at the index 251 func (v *Vector[T]) Set(index int, value T) { 252 v.SetNew(index, value) 253 } 254 255 // SetNew puts an element into the vector at the index 256 func (v *Vector[T]) SetNew(index int, value T) bool { 257 if v == nil { 258 return false 259 } 260 e := *v 261 if index < 0 { 262 return false 263 } 264 l := len(e) 265 if index >= l { 266 c := l * 2 267 l := index + 1 268 if l > c { 269 c = l 270 } 271 ne := make([]T, l, c) 272 copy(ne, e) 273 e = ne 274 *v = e 275 } 276 e[index] = value 277 return true 278 } 279 280 // Filter returns a loop consisting of vector elements matching the filter 281 func (v *Vector[T]) Filter(filter func(T) bool) loop.Loop[T] { 282 return loop.Filter(v.Loop(), filter) 283 } 284 285 // Filt returns a breakable loop consisting of elements that satisfy the condition of the 'predicate' function 286 func (v *Vector[T]) Filt(predicate func(T) (bool, error)) breakLoop.Loop[T] { 287 return loop.Filt(v.Loop(), predicate) 288 } 289 290 // Convert returns a loop that applies the 'converter' function to the collection elements 291 func (v *Vector[T]) Convert(converter func(T) T) loop.Loop[T] { 292 return loop.Convert(v.Loop(), converter) 293 } 294 295 // Conv returns a breakable loop that applies the 'converter' function to the collection elements 296 func (v *Vector[T]) Conv(converter func(T) (T, error)) breakLoop.Loop[T] { 297 return loop.Conv(v.Loop(), converter) 298 } 299 300 // Reduce reduces the elements into an one using the 'merge' function 301 func (v *Vector[T]) Reduce(merge func(T, T) T) (out T) { 302 if v != nil { 303 out = slice.Reduce(*v, merge) 304 } 305 return out 306 } 307 308 // HasAny finds the first element that satisfies the 'predicate' function condition and returns true if successful 309 func (v *Vector[T]) HasAny(predicate func(T) bool) (ok bool) { 310 if v != nil { 311 ok = slice.HasAny(*v, predicate) 312 } 313 return ok 314 } 315 316 // Sort sorts the Vector in-place and returns it 317 func (v *Vector[T]) Sort(comparer slice.Comparer[T]) *Vector[T] { 318 return v.sortBy(slice.Sort, comparer) 319 } 320 321 // StableSort stable sorts the Vector in-place and returns it 322 func (v *Vector[T]) StableSort(comparer slice.Comparer[T]) *Vector[T] { 323 return v.sortBy(slice.StableSort, comparer) 324 } 325 326 func (v *Vector[T]) sortBy(sorter func([]T, slice.Comparer[T]) []T, comparer slice.Comparer[T]) *Vector[T] { 327 if v != nil { 328 sorter(*v, comparer) 329 } 330 return v 331 } 332 333 // String returns then string representation 334 func (v *Vector[T]) String() string { 335 if v == nil { 336 return "" 337 } 338 return slice.ToString(*v) 339 }