mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-16 11:23:11 -06:00
58 lines
1.6 KiB
Go
58 lines
1.6 KiB
Go
package util
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
)
|
|
|
|
// Unique removes duplicate items from a sorted list in place.
|
|
// Takes the same interface as sort.Sort
|
|
// Returns the length of the data without duplicates
|
|
// Uses the last occurrence of a duplicate.
|
|
// O(n).
|
|
func Unique(data sort.Interface) int {
|
|
if !sort.IsSorted(data) {
|
|
panic(fmt.Errorf("util: the input to Unique() must be sorted"))
|
|
}
|
|
|
|
if data.Len() == 0 {
|
|
return 0
|
|
}
|
|
length := data.Len()
|
|
// j is the next index to output an element to.
|
|
j := 0
|
|
for i := 1; i < length; i++ {
|
|
// If the previous element is less than this element then they are
|
|
// not equal. Otherwise they must be equal because the list is sorted.
|
|
// If they are equal then we move onto the next element.
|
|
if data.Less(i-1, i) {
|
|
// "Write" the previous element to the output position by swapping
|
|
// the elements.
|
|
// Note that if the list has no duplicates then i-1 == j so the
|
|
// swap does nothing. (This assumes that data.Swap(a,b) nops if a==b)
|
|
data.Swap(i-1, j)
|
|
// Advance to the next output position in the list.
|
|
j++
|
|
}
|
|
}
|
|
// Output the last element.
|
|
data.Swap(length-1, j)
|
|
return j + 1
|
|
}
|
|
|
|
// SortAndUnique sorts a list and removes duplicate entries in place.
|
|
// Takes the same interface as sort.Sort
|
|
// Returns the length of the data without duplicates
|
|
// Uses the last occurrence of a duplicate.
|
|
// O(nlog(n))
|
|
func SortAndUnique(data sort.Interface) int {
|
|
sort.Sort(data)
|
|
return Unique(data)
|
|
}
|
|
|
|
// UniqueStrings turns a list of strings into a sorted list of unique strings.
|
|
// O(nlog(n))
|
|
func UniqueStrings(strings []string) []string {
|
|
return strings[:SortAndUnique(sort.StringSlice(strings))]
|
|
}
|