From 4c8193876fb45ce3da251be01f19fd1332e9b65a Mon Sep 17 00:00:00 2001 From: James Shubin Date: Tue, 3 Jul 2018 20:45:55 -0400 Subject: [PATCH] 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. --- util/util.go | 38 +++++++++++++++++++++++++++++++++++ util/util_test.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/util/util.go b/util/util.go index d730fb64..bb1e859b 100644 --- a/util/util.go +++ b/util/util.go @@ -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 +} diff --git a/util/util_test.go b/util/util_test.go index f0c745a9..c34e0e15 100644 --- a/util/util_test.go +++ b/util/util_test.go @@ -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) + } +}