Skip to content

Commit

Permalink
Add ElementsMatch, ElementsMatchBy
Browse files Browse the repository at this point in the history
  • Loading branch information
senago committed Feb 7, 2025
1 parent 70b763e commit 28747ed
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
42 changes: 42 additions & 0 deletions intersect.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,45 @@ func WithoutNth[T comparable, Slice ~[]T](collection Slice, nths ...int) Slice {

return result
}

// ElementsMatch returns true if lists
// contain the same set of elements (including empty set).
//
// If there are duplicate elements,
// the number of appearances of each of them in both lists should match.
func ElementsMatch[T comparable, Slice ~[]T](list1 Slice, list2 Slice) bool {
return ElementsMatchBy(list1, list2, func(item T) T { return item })
}

// ElementsMatchBy returns true if lists
// contain the same set of elements' keys (including empty set).
//
// If there are duplicate keys,
// the number of appearances of each of them in both lists should match.
func ElementsMatchBy[T any, K comparable](list1 []T, list2 []T, iteratee func(item T) K) bool {
if len(list1) != len(list2) {
return false
}

if len(list1) == 0 {
return true
}

counters := make(map[K]int, len(list1))

for _, el := range list1 {
counters[iteratee(el)]++
}

for _, el := range list2 {
counters[iteratee(el)]--
}

for _, count := range counters {
if count != 0 {
return false
}
}

return true
}
16 changes: 16 additions & 0 deletions intersect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,19 @@ func TestWithoutNth(t *testing.T) {
nonempty := WithoutNth(allStrings)
is.IsType(nonempty, allStrings, "type preserved")
}

func TestElementsMatch(t *testing.T) {
t.Parallel()
is := assert.New(t)

is.False(ElementsMatch([]int{}, []int{1}))
is.False(ElementsMatch([]int{1}, []int{2}))
is.False(ElementsMatch([]int{1}, []int{1, 2}))
is.False(ElementsMatch([]int{1, 1, 2}, []int{2, 2, 1}))

is.True(ElementsMatch([]int{}, nil))
is.True(ElementsMatch([]int{1}, []int{1}))
is.True(ElementsMatch([]int{1, 1}, []int{1, 1}))
is.True(ElementsMatch([]int{1, 2}, []int{2, 1}))
is.True(ElementsMatch([]int{1, 1, 2}, []int{1, 2, 1}))
}

0 comments on commit 28747ed

Please sign in to comment.