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  }