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