util: Add PathSlice type that satisfies sort.Interface
This commit adds a []string{} type alias named PathSlice, and the
Len(), Swap(), and Less() methods required to satisfy sort.Interface.
Now you can do `sort.Sort(util.PathSlice(foo))` where foo is a slice
of paths. It will be sorted by depth in alphabetical order.
This commit is contained in:
35
util/util.go
35
util/util.go
@@ -420,3 +420,38 @@ func SortedStrSliceCompare(a, b []string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PathSlice is a type used to implement sort.Interface on a slice of strings,
|
||||
// where each string is a path. This allows you to call sort.Sort() on a list
|
||||
// of paths, after casting the []string{} to this type. Paths will be sorted
|
||||
// by depth in alphabetical order.
|
||||
type PathSlice []string
|
||||
|
||||
// Len returns the length of obj. It is required to satisfy sort.Interface.
|
||||
func (obj PathSlice) Len() int {
|
||||
return len(obj)
|
||||
}
|
||||
|
||||
// Swap swaps obj[i] and obj[j]. it is required to satisfy sort.Interface.
|
||||
func (obj PathSlice) Swap(i, j int) {
|
||||
obj[i], obj[j] = obj[j], obj[i]
|
||||
}
|
||||
|
||||
// Less returns whether obj[i] is less than obj[j]. It performs the logic
|
||||
// required to satisfy sort.Interface.
|
||||
func (obj PathSlice) Less(i, j int) bool {
|
||||
x := PathSplitFullReversed(obj[i])
|
||||
y := PathSplitFullReversed(obj[j])
|
||||
if x[0] != y[0] {
|
||||
return x[0] < y[0]
|
||||
}
|
||||
if len(x) > len(y) {
|
||||
return false
|
||||
}
|
||||
for i := range x {
|
||||
if x[i] > y[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -857,3 +857,51 @@ func TestSortedStrSliceCompare3(t *testing.T) {
|
||||
t.Errorf("input slice reordered to: %v", slice1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPathSliceSort(t *testing.T) {
|
||||
tests := []struct {
|
||||
in []string
|
||||
out []string
|
||||
}{
|
||||
{
|
||||
in: []string{
|
||||
"/foo/bar/baz",
|
||||
"/bing/bang/boom",
|
||||
"/1/2/3/",
|
||||
"/foo/bar/raz",
|
||||
"/bing/buzz/",
|
||||
"/foo/",
|
||||
"/",
|
||||
"/1/",
|
||||
"/foo/bar/baz/bam",
|
||||
"/bing/bang/",
|
||||
"/1/2/",
|
||||
"/foo/bar/",
|
||||
"/bing/",
|
||||
},
|
||||
out: []string{
|
||||
"/",
|
||||
"/1/",
|
||||
"/1/2/",
|
||||
"/1/2/3/",
|
||||
"/bing/",
|
||||
"/bing/bang/",
|
||||
"/bing/bang/boom",
|
||||
"/bing/buzz/",
|
||||
"/foo/",
|
||||
"/foo/bar/",
|
||||
"/foo/bar/baz",
|
||||
"/foo/bar/baz/bam",
|
||||
"/foo/bar/raz",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
sort.Sort(PathSlice(tt.in))
|
||||
for i := range tt.in {
|
||||
if tt.in[i] != tt.out[i] {
|
||||
t.Errorf("path sort failed: wanted: %s got: %s", tt.out[i], tt.in[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user