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  }