Merge "Add SortedStringValues and SortedUniqueStringValues"
This commit is contained in:
commit
a00cb70910
2 changed files with 153 additions and 5 deletions
|
@ -65,21 +65,55 @@ func JoinWithSuffix(strs []string, suffix string, separator string) string {
|
|||
return buf.String()
|
||||
}
|
||||
|
||||
// SorterStringKeys returns the keys of the given string-keyed map in the ascending order
|
||||
// SorterStringKeys returns the keys of the given string-keyed map in the ascending order.
|
||||
func SortedStringKeys(m interface{}) []string {
|
||||
v := reflect.ValueOf(m)
|
||||
if v.Kind() != reflect.Map {
|
||||
panic(fmt.Sprintf("%#v is not a map", m))
|
||||
}
|
||||
keys := v.MapKeys()
|
||||
s := make([]string, 0, len(keys))
|
||||
for _, key := range keys {
|
||||
s = append(s, key.String())
|
||||
if v.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
iter := v.MapRange()
|
||||
s := make([]string, 0, v.Len())
|
||||
for iter.Next() {
|
||||
s = append(s, iter.Key().String())
|
||||
}
|
||||
sort.Strings(s)
|
||||
return s
|
||||
}
|
||||
|
||||
// stringValues returns the values of the given string-valued map in randomized map order.
|
||||
func stringValues(m interface{}) []string {
|
||||
v := reflect.ValueOf(m)
|
||||
if v.Kind() != reflect.Map {
|
||||
panic(fmt.Sprintf("%#v is not a map", m))
|
||||
}
|
||||
if v.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
iter := v.MapRange()
|
||||
s := make([]string, 0, v.Len())
|
||||
for iter.Next() {
|
||||
s = append(s, iter.Value().String())
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// SortedStringValues returns the values of the given string-valued map in the ascending order.
|
||||
func SortedStringValues(m interface{}) []string {
|
||||
s := stringValues(m)
|
||||
sort.Strings(s)
|
||||
return s
|
||||
}
|
||||
|
||||
// SortedUniqueStringValues returns the values of the given string-valued map in the ascending order
|
||||
// with duplicates removed.
|
||||
func SortedUniqueStringValues(m interface{}) []string {
|
||||
s := stringValues(m)
|
||||
return SortedUniqueStrings(s)
|
||||
}
|
||||
|
||||
// IndexList returns the index of the first occurrence of the given string in the list or -1
|
||||
func IndexList(s string, list []string) int {
|
||||
for i, l := range list {
|
||||
|
|
|
@ -640,3 +640,117 @@ func BenchmarkFirstUniqueStrings(b *testing.B) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortedStringKeys(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
in interface{}
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "nil",
|
||||
in: map[string]string(nil),
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
in: map[string]string{},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "simple",
|
||||
in: map[string]string{"a": "foo", "b": "bar"},
|
||||
expected: []string{"a", "b"},
|
||||
},
|
||||
{
|
||||
name: "interface values",
|
||||
in: map[string]interface{}{"a": nil, "b": nil},
|
||||
expected: []string{"a", "b"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range testCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := SortedStringKeys(tt.in)
|
||||
if g, w := got, tt.expected; !reflect.DeepEqual(g, w) {
|
||||
t.Errorf("wanted %q, got %q", w, g)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortedStringValues(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
in interface{}
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "nil",
|
||||
in: map[string]string(nil),
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
in: map[string]string{},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "simple",
|
||||
in: map[string]string{"foo": "a", "bar": "b"},
|
||||
expected: []string{"a", "b"},
|
||||
},
|
||||
{
|
||||
name: "duplicates",
|
||||
in: map[string]string{"foo": "a", "bar": "b", "baz": "b"},
|
||||
expected: []string{"a", "b", "b"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range testCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := SortedStringValues(tt.in)
|
||||
if g, w := got, tt.expected; !reflect.DeepEqual(g, w) {
|
||||
t.Errorf("wanted %q, got %q", w, g)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortedUniqueStringValues(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
in interface{}
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "nil",
|
||||
in: map[string]string(nil),
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
in: map[string]string{},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "simple",
|
||||
in: map[string]string{"foo": "a", "bar": "b"},
|
||||
expected: []string{"a", "b"},
|
||||
},
|
||||
{
|
||||
name: "duplicates",
|
||||
in: map[string]string{"foo": "a", "bar": "b", "baz": "b"},
|
||||
expected: []string{"a", "b"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range testCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := SortedUniqueStringValues(tt.in)
|
||||
if g, w := got, tt.expected; !reflect.DeepEqual(g, w) {
|
||||
t.Errorf("wanted %q, got %q", w, g)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue