diff --git a/android/util.go b/android/util.go index e21e66b88..3c0af2f38 100644 --- a/android/util.go +++ b/android/util.go @@ -201,6 +201,12 @@ func ListSetDifference[T comparable](l1, l2 []T) (bool, []T, []T) { return listsDiffer, diff1, diff2 } +// Returns true if the two lists have common elements. +func HasIntersection[T comparable](l1, l2 []T) bool { + _, a, b := ListSetDifference(l1, l2) + return len(a)+len(b) < len(setFromList(l1))+len(setFromList(l2)) +} + // Returns true if the given string s is prefixed with any string in the given prefix list. func HasAnyPrefix(s string, prefixList []string) bool { for _, prefix := range prefixList { diff --git a/android/util_test.go b/android/util_test.go index 8e73d835c..6537d69b9 100644 --- a/android/util_test.go +++ b/android/util_test.go @@ -818,3 +818,52 @@ func TestReverseSlice(t *testing.T) { }) } } + +var hasIntersectionTestCases = []struct { + name string + l1 []string + l2 []string + expected bool +}{ + { + name: "empty", + l1: []string{"a", "b", "c"}, + l2: []string{}, + expected: false, + }, + { + name: "both empty", + l1: []string{}, + l2: []string{}, + expected: false, + }, + { + name: "identical", + l1: []string{"a", "b", "c"}, + l2: []string{"a", "b", "c"}, + expected: true, + }, + { + name: "duplicates", + l1: []string{"a", "a", "a"}, + l2: []string{"a", "b", "c"}, + expected: true, + }, + { + name: "duplicates with no intersection", + l1: []string{"d", "d", "d", "d"}, + l2: []string{"a", "b", "c"}, + expected: false, + }, +} + +func TestHasIntersection(t *testing.T) { + for _, testCase := range hasIntersectionTestCases { + t.Run(testCase.name, func(t *testing.T) { + hasIntersection := HasIntersection(testCase.l1, testCase.l2) + if !reflect.DeepEqual(hasIntersection, testCase.expected) { + t.Errorf("expected %#v, got %#v", testCase.expected, hasIntersection) + } + }) + } +}