util: Add a UInt64Slice and associated sorting functionality.

This adds an easy to sort slice of uint64's and associated functionality
to sort a list of strings by their associated order in a map indexed by
uint64's.
This commit is contained in:
James Shubin
2018-07-03 20:45:55 -04:00
parent 158bc1eb2a
commit 4c8193876f
2 changed files with 88 additions and 0 deletions

View File

@@ -455,3 +455,41 @@ func (obj PathSlice) Less(i, j int) bool {
}
return true
}
// UInt64Slice attaches the methods of sort.Interface to []uint64, sorting in
// increasing order.
type UInt64Slice []uint64
// Len returns the length of the slice of uint64's.
func (obj UInt64Slice) Len() int { return len(obj) }
// Less returns the smaller element in the sort order.
func (obj UInt64Slice) Less(i, j int) bool { return obj[i] < obj[j] }
// Swap swaps two elements in the slice.
func (obj UInt64Slice) Swap(i, j int) { obj[i], obj[j] = obj[j], obj[i] }
// Sort is a convenience method.
func (obj UInt64Slice) Sort() { sort.Sort(obj) }
// SortMapStringValuesByUInt64Keys builds a list of strings, sorted by the
// corresponding key that is associated with that value.
// TODO: add some tests
func SortMapStringValuesByUInt64Keys(m map[uint64]string) []string {
//if m == nil { // no need to special case this, range handles it safely
// return []string{}
//}
keys := []uint64{}
for i := range m {
keys = append(keys, i)
}
sort.Sort(UInt64Slice(keys))
result := []string{}
for _, key := range keys {
s := m[key]
result = append(result, s)
}
return result
}

View File

@@ -905,3 +905,53 @@ func TestPathSliceSort(t *testing.T) {
}
}
}
func TestSortUInt64Slice(t *testing.T) {
slice0 := []uint64{42, 13, 0}
sort.Sort(UInt64Slice(slice0))
if slice0[0] != 0 || slice0[1] != 13 || slice0[2] != 42 {
t.Errorf("input slice reordered to: %v", slice0)
}
slice1 := []uint64{99, 12, 13}
sort.Sort(UInt64Slice(slice1))
if slice1[0] != 12 || slice1[1] != 13 || slice1[2] != 99 {
t.Errorf("input slice reordered to: %v", slice1)
}
}
func TestSortMapStringValuesByUInt64Keys(t *testing.T) {
if x := len(SortMapStringValuesByUInt64Keys(nil)); x != 0 {
t.Errorf("input map of nil caused a: %d", x)
}
map0 := map[uint64]string{
42: "world",
34: "there",
13: "hello",
}
slice0 := SortMapStringValuesByUInt64Keys(map0)
if slice0[0] != "hello" || slice0[1] != "there" || slice0[2] != "world" {
t.Errorf("input slice reordered to: %v", slice0)
}
map1 := map[uint64]string{
99: "a",
12: "c",
13: "b",
}
slice1 := SortMapStringValuesByUInt64Keys(map1)
if slice1[0] != "c" || slice1[1] != "b" || slice1[2] != "a" {
t.Errorf("input slice reordered to: %v", slice1)
}
map2 := map[uint64]string{
12: "c",
0: "d",
44442: "b",
}
slice2 := SortMapStringValuesByUInt64Keys(map2)
if slice2[0] != "d" || slice2[1] != "c" || slice2[2] != "b" {
t.Errorf("input slice reordered to: %v", slice2)
}
}