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  }