github.com/mymmsc/gox@v1.3.33/api/slices_unique.go (about)

     1  package api
     2  
     3  import "sort"
     4  
     5  // Interface Types that implement unique.Interface can have duplicate elements removed by
     6  // the functionality in this package.
     7  type Interface interface {
     8  	sort.Interface
     9  
    10  	// Truncate reduces the length to the first n elements.
    11  	Truncate(n int)
    12  }
    13  
    14  // Unique removes duplicate elements from data. It assumes sort.IsSorted(data).
    15  func Unique(data Interface) {
    16  	data.Truncate(ToFront(data))
    17  }
    18  
    19  // ToFront reports the number of unique elements of data which it moves to the
    20  // first n positions. It assumes sort.IsSorted(data).
    21  func ToFront(data sort.Interface) (n int) {
    22  	n = data.Len()
    23  	if n == 0 {
    24  		return
    25  	}
    26  	k := 0
    27  	for i := 1; i < n; i++ {
    28  		if data.Less(k, i) {
    29  			k++
    30  			data.Swap(k, i)
    31  		}
    32  	}
    33  	return k + 1
    34  }
    35  
    36  // Sort sorts and removes duplicate entries from data.
    37  func Sort(data Interface) {
    38  	sort.Sort(data)
    39  	Unique(data)
    40  }
    41  
    42  // IsUniqued reports whether the elements in data are sorted and unique.
    43  func IsUniqued(data sort.Interface) bool {
    44  	n := data.Len()
    45  	for i := n - 1; i > 0; i-- {
    46  		if !data.Less(i-1, i) {
    47  			return false
    48  		}
    49  	}
    50  	return true
    51  }
    52  
    53  // Float64Slice attaches the methods of Interface to []float64.
    54  type Float64Slice struct{ P *[]float64 }
    55  
    56  func (p Float64Slice) Len() int           { return len(*p.P) }
    57  func (p Float64Slice) Swap(i, j int)      { (*p.P)[i], (*p.P)[j] = (*p.P)[j], (*p.P)[i] }
    58  func (p Float64Slice) Less(i, j int) bool { return (*p.P)[i] < (*p.P)[j] }
    59  func (p Float64Slice) Truncate(n int)     { *p.P = (*p.P)[:n] }
    60  
    61  // Float64s removes duplicate elements from a sorted slice of float64s.
    62  func Float64s(a *[]float64) { Unique(Float64Slice{a}) }
    63  
    64  // Float64sAreUnique tests whether a slice of float64s is sorted and its
    65  // elements are unique.
    66  func Float64sAreUnique(a []float64) bool { return IsUniqued(sort.Float64Slice(a)) }
    67  
    68  // IntSlice attaches the methods of Interface to []int.
    69  type IntSlice struct{ P *[]int }
    70  
    71  func (p IntSlice) Len() int           { return len(*p.P) }
    72  func (p IntSlice) Swap(i, j int)      { (*p.P)[i], (*p.P)[j] = (*p.P)[j], (*p.P)[i] }
    73  func (p IntSlice) Less(i, j int) bool { return (*p.P)[i] < (*p.P)[j] }
    74  func (p IntSlice) Truncate(n int)     { *p.P = (*p.P)[:n] }
    75  
    76  // Ints removes duplicate elements from a sorted slice of ints.
    77  func Ints(a *[]int) { Unique(IntSlice{a}) }
    78  
    79  // IntsAreUnique tests whether a slice of ints is sorted and its elements are
    80  // unique.
    81  func IntsAreUnique(a []int) bool { return IsUniqued(sort.IntSlice(a)) }
    82  
    83  // StringSlice attaches the methods of Interface to []string.
    84  type StringSlice struct{ P *[]string }
    85  
    86  func (p StringSlice) Len() int           { return len(*p.P) }
    87  func (p StringSlice) Swap(i, j int)      { (*p.P)[i], (*p.P)[j] = (*p.P)[j], (*p.P)[i] }
    88  func (p StringSlice) Less(i, j int) bool { return (*p.P)[i] < (*p.P)[j] }
    89  func (p StringSlice) Truncate(n int)     { *p.P = (*p.P)[:n] }
    90  
    91  // Strings removes duplicate elements from a sorted slice of strings.
    92  func Strings(a *[]string) { Unique(StringSlice{a}) }
    93  
    94  // StringsAreUnique tests whether a slice of strings is sorted and its elements
    95  // are unique.
    96  func StringsAreUnique(a []string) bool { return IsUniqued(sort.StringSlice(a)) }