github.com/haraldrudell/parl@v0.4.176/pslices/ordered.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 provides somehat outdated slice functions such as ordered slices
     7  package pslices
     8  
     9  import (
    10  	"github.com/haraldrudell/parl/parli"
    11  	"golang.org/x/exp/constraints"
    12  	"golang.org/x/exp/slices"
    13  )
    14  
    15  // Ordered is an ordered slice overwriting duplicates implementing [parl.Ordered][E any].
    16  //   - E must be a comparable and ordered type, ie. not slice func map.
    17  //   - Insert overwrites duplicates and is O(log n)
    18  //   - Delete removes the first occurrence O(log n)
    19  //   - For custom sort order or slice func map types, use NewOrderedAny
    20  type Ordered[E constraints.Ordered] struct {
    21  	Slice[E]
    22  }
    23  
    24  // NewOrdered returns a slice ordered by value.
    25  func NewOrdered[E constraints.Ordered]() (list parli.Ordered[E]) {
    26  	return &Ordered[E]{}
    27  }
    28  
    29  // Insert adds an element to an ordered slice.
    30  //   - Insert overwrites duplicates and is O(log n)
    31  func (o *Ordered[E]) Insert(element E) {
    32  	if position, wasFound := slices.BinarySearch(o.list, element); wasFound {
    33  		o.list[position] = element
    34  	} else {
    35  		o.list = slices.Insert(o.list, position, element)
    36  	}
    37  }
    38  
    39  // Delete removes an element from an ordered slice.
    40  //   - if the element is not in the slice, the slice is not changed
    41  //   - is the slice has duplicates, the first occurrence is removed
    42  //   - O(log n)
    43  func (o *Ordered[E]) Delete(element E) {
    44  	if position, wasFound := slices.BinarySearch(o.list, element); wasFound {
    45  		o.list = slices.Delete(o.list, position, position+1)
    46  	}
    47  }
    48  
    49  func (o *Ordered[E]) Index(element E) (index int) {
    50  	var wasFound bool
    51  	if index, wasFound = slices.BinarySearch(o.list, element); !wasFound {
    52  		index = -1
    53  	}
    54  	return
    55  }
    56  
    57  func (o *Ordered[E]) Clone() (o2 parli.Ordered[E]) {
    58  	return &Ordered[E]{Slice: *o.Slice.Clone()}
    59  }