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