Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2a222db

Browse files
committedFeb 7, 2025·
Add ElementsMatch, ElementsMatchBy
1 parent 70b763e commit 2a222db

File tree

3 files changed

+103
-0
lines changed

3 files changed

+103
-0
lines changed
 

‎README.md

+30
Original file line numberDiff line numberDiff line change
@@ -2348,6 +2348,36 @@ subset := lo.WithoutNth([]int{-2, -1, 0, 1, 2}, 3, -42, 1)
23482348
// []int{-2, 0, 2}
23492349
```
23502350

2351+
### ElementsMatch
2352+
2353+
ElementsMatch returns true if lists
2354+
contain the same set of elements (including empty set).
2355+
2356+
If there are duplicate elements,
2357+
the number of appearances of each of them in both lists should match.
2358+
2359+
```go
2360+
b := lo.ElementsMatch([]int{1, 1, 2}, []int{2, 1, 1})
2361+
// true
2362+
```
2363+
2364+
### ElementsMatchBy
2365+
2366+
ElementsMatchBy returns true if lists
2367+
contain the same set of elements' keys (including empty set).
2368+
2369+
If there are duplicate keys,
2370+
the number of appearances of each of them in both lists should match.
2371+
2372+
```go
2373+
b := lo.ElementsMatchBy(
2374+
[]someType{a, b},
2375+
[]someType{b, a},
2376+
func(item someType) string { return item.ID() },
2377+
)
2378+
// true
2379+
```
2380+
23512381
### IndexOf
23522382

23532383
Returns the index at which the first occurrence of a value is found in an array or return -1 if the value cannot be found.

‎intersect.go

+42
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,45 @@ func WithoutNth[T comparable, Slice ~[]T](collection Slice, nths ...int) Slice {
225225

226226
return result
227227
}
228+
229+
// ElementsMatch returns true if lists
230+
// contain the same set of elements (including empty set).
231+
//
232+
// If there are duplicate elements,
233+
// the number of appearances of each of them in both lists should match.
234+
func ElementsMatch[T comparable, Slice ~[]T](list1 Slice, list2 Slice) bool {
235+
return ElementsMatchBy(list1, list2, func(item T) T { return item })
236+
}
237+
238+
// ElementsMatchBy returns true if lists
239+
// contain the same set of elements' keys (including empty set).
240+
//
241+
// If there are duplicate keys,
242+
// the number of appearances of each of them in both lists should match.
243+
func ElementsMatchBy[T any, K comparable](list1 []T, list2 []T, iteratee func(item T) K) bool {
244+
if len(list1) != len(list2) {
245+
return false
246+
}
247+
248+
if len(list1) == 0 {
249+
return true
250+
}
251+
252+
counters := make(map[K]int, len(list1))
253+
254+
for _, el := range list1 {
255+
counters[iteratee(el)]++
256+
}
257+
258+
for _, el := range list2 {
259+
counters[iteratee(el)]--
260+
}
261+
262+
for _, count := range counters {
263+
if count != 0 {
264+
return false
265+
}
266+
}
267+
268+
return true
269+
}

‎intersect_test.go

+31
Original file line numberDiff line numberDiff line change
@@ -330,3 +330,34 @@ func TestWithoutNth(t *testing.T) {
330330
nonempty := WithoutNth(allStrings)
331331
is.IsType(nonempty, allStrings, "type preserved")
332332
}
333+
334+
func TestElementsMatch(t *testing.T) {
335+
t.Parallel()
336+
is := assert.New(t)
337+
338+
is.False(ElementsMatch([]int{}, []int{1}))
339+
is.False(ElementsMatch([]int{1}, []int{2}))
340+
is.False(ElementsMatch([]int{1}, []int{1, 2}))
341+
is.False(ElementsMatch([]int{1, 1, 2}, []int{2, 2, 1}))
342+
343+
is.True(ElementsMatch([]int{}, nil))
344+
is.True(ElementsMatch([]int{1}, []int{1}))
345+
is.True(ElementsMatch([]int{1, 1}, []int{1, 1}))
346+
is.True(ElementsMatch([]int{1, 2}, []int{2, 1}))
347+
is.True(ElementsMatch([]int{1, 1, 2}, []int{1, 2, 1}))
348+
}
349+
350+
func TestElementsMatchBy(t *testing.T) {
351+
t.Parallel()
352+
is := assert.New(t)
353+
354+
type someType struct {
355+
key string
356+
}
357+
358+
is.True(ElementsMatchBy(
359+
[]someType{{key: "a"}, {key: "b"}},
360+
[]someType{{key: "b"}, {key: "a"}},
361+
func(item someType) string { return item.key },
362+
))
363+
}

0 commit comments

Comments
 (0)
Please sign in to comment.