github.com/haraldrudell/parl@v0.4.176/pslices/slice.go (about)

     1  /*
     2  © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package pslices
     7  
     8  import (
     9  	"golang.org/x/exp/slices"
    10  )
    11  
    12  // Slice is a base type for reusable slice implementations
    13  //   - super-types could implement Insert Delete Index
    14  //   - Length
    15  //   - Element single-element access
    16  //   - Slice multiple-element access
    17  //   - DeleteIndex delete elements
    18  //   - Clear Clone
    19  //   - List clone of n first items
    20  //   - Slice implements parl.Slice[E any].
    21  type Slice[E any] struct {
    22  	list []E
    23  }
    24  
    25  // Element returns element by index.
    26  // if index is negative or the length of the slice or larger, the E zero-value is returned.
    27  func (o *Slice[E]) Element(index int) (element E) {
    28  	if index >= 0 && index < len(o.list) {
    29  		element = o.list[index]
    30  	}
    31  	return
    32  }
    33  
    34  // Slice returns a multiple-element sub-slice
    35  func (o *Slice[E]) SubSlice(index0, index1 int) (elements []E) {
    36  	if index0 >= 0 && index0 <= index1 && index1 <= len(o.list) {
    37  		elements = o.list[index0:index1]
    38  	}
    39  	return
    40  }
    41  
    42  func (o *Slice[E]) SetElement(index int, element E) {
    43  	if index < 0 {
    44  		index = 0
    45  	}
    46  	if index >= cap(o.list) {
    47  		list := o.list
    48  		o.list = make([]E, index+1)
    49  		copy(o.list, list)
    50  	} else if index >= len(o.list) {
    51  		o.list = o.list[:index+1]
    52  	}
    53  	o.list[index] = element
    54  }
    55  
    56  // Append adds element at end
    57  func (o *Slice[E]) Append(slice []E) {
    58  	o.list = append(o.list, slice...)
    59  }
    60  
    61  // DeleteIndex removes elements by index
    62  //   - index1 default is slice length
    63  func (o *Slice[E]) DeleteIndex(index0 int, index1 ...int) {
    64  	length := len(o.list)
    65  	var index2 int
    66  	if len(index1) > 0 {
    67  		index2 = index1[0]
    68  	} else {
    69  		index2 = length
    70  	}
    71  
    72  	// ensure indexes are valid
    73  	if index0 < 0 {
    74  		index0 = 0
    75  	} else if index0 > length {
    76  		index0 = length
    77  	}
    78  	if index2 < index0 {
    79  		index2 = index0
    80  	} else if index2 > length {
    81  		index2 = length
    82  	}
    83  
    84  	// execute delete
    85  	if index0 == index2 {
    86  		return // nothing to do return
    87  	} else if index0 == 0 {
    88  
    89  		// delete at beginning
    90  		TrimLeft(&o.list, index2)
    91  		return
    92  	} else if index2 == length {
    93  
    94  		// delete at end
    95  		SetLength(&o.list, index0)
    96  		return // delete at end return
    97  	}
    98  
    99  	// delete in the middle
   100  	deleteCount := index2 - index0
   101  	copy(o.list[index0:], o.list[index2:])
   102  	SetLength(&o.list, length-deleteCount)
   103  }
   104  
   105  // Length returns number of elements in the slice
   106  func (o *Slice[E]) Length() (index int) {
   107  	return len(o.list)
   108  }
   109  
   110  // Cap returns slice capacity
   111  func (o *Slice[E]) Cap() (capacity int) {
   112  	return cap(o.list)
   113  }
   114  
   115  // Clear empties the ordered slice
   116  func (o *Slice[E]) Clear() {
   117  	o.list = o.list[:0]
   118  }
   119  
   120  // Clone returns a shallow clone of the slice
   121  func (o *Slice[E]) Clone() (clone *Slice[E]) {
   122  	return &Slice[E]{list: slices.Clone(o.list)}
   123  }
   124  
   125  // List returns a clone of the n or all first slice elements
   126  func (o *Slice[E]) List(n ...int) (list []E) {
   127  	length := o.Length()
   128  
   129  	// get number of items n0
   130  	var n0 int
   131  	if len(n) > 0 {
   132  		n0 = n[0]
   133  	}
   134  	if n0 < 1 || n0 > length {
   135  		n0 = length
   136  	}
   137  
   138  	return slices.Clone(o.list[:n0])
   139  }