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)) }