diff --git a/pkgs/misc/misc.go b/pkgs/misc/misc.go index 2908b55..7e7dd9f 100644 --- a/pkgs/misc/misc.go +++ b/pkgs/misc/misc.go @@ -56,3 +56,23 @@ func Merge(a map[string]string, b map[string]string) { a[k] = v } } + +// Removes duplicate entries from the given string slice and returns a slice +// with the unique values +func RemoveDuplicates(in []string) (out []string) { + // use a map to "remove" duplicates. the value in the map is totally + // irrelevant + outMap := make(map[string]bool) + for _, s := range in { + if ok := outMap[s]; !ok { + outMap[s] = true + } + } + + out = make([]string, 0, len(outMap)) + for k := range outMap { + out = append(out, k) + } + + return +} diff --git a/pkgs/misc/misc_test.go b/pkgs/misc/misc_test.go index 2d5e9b8..ecca6d6 100644 --- a/pkgs/misc/misc_test.go +++ b/pkgs/misc/misc_test.go @@ -5,6 +5,7 @@ package misc import ( "reflect" + "sort" "testing" ) @@ -69,3 +70,56 @@ func TestMerge(t *testing.T) { }) } } + +func TestRemoveDuplicates(t *testing.T) { + subtests := []struct { + name string + in []string + expected []string + }{ + { + name: "no duplicates", + in: []string{ + "foo", + "bar", + "banana", + "airplane", + }, + expected: []string{ + "foo", + "bar", + "banana", + "airplane", + }, + }, + { + name: "all duplicates", + in: []string{ + "foo", + "foo", + "foo", + "foo", + }, + expected: []string{ + "foo", + }, + }, + { + name: "empty", + in: []string{}, + expected: []string{}, + }, + } + + for _, st := range subtests { + t.Run(st.name, func(t *testing.T) { + // note: sorting to make comparison easier later + sort.Strings(st.expected) + out := RemoveDuplicates(st.in) + sort.Strings(out) + if !reflect.DeepEqual(st.expected, out) { + t.Fatalf("expected: %q, got: %q\n", st.expected, out) + } + }) + } +}