Skip to content

Commit 6a535ac

Browse files
committed
add intersect.SymmetricDifference
1 parent 71d8341 commit 6a535ac

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ Supported intersection helpers:
180180
- [NoneBy](#noneby)
181181
- [Intersect](#intersect)
182182
- [Difference](#difference)
183+
- [SymmetricDifference](#symmetric_difference)
183184
- [Union](#union)
184185
- [Without](#without)
185186
- [WithoutEmpty](#withoutempty)
@@ -1720,6 +1721,21 @@ left, right := lo.Difference([]int{0, 1, 2, 3, 4, 5}, []int{0, 1, 2, 3, 4, 5})
17201721
// []int{}, []int{}
17211722
```
17221723

1724+
### SymmetricDifference
1725+
1726+
Returns the symmetric difference between two collections.
1727+
1728+
Returns all elements which are in either of the collections but not in both.
1729+
Does not preserve order of elements.
1730+
1731+
```go
1732+
left, right := lo.Difference([]int{0, 1, 2, 3, 4, 5}, []int{0, 2, 6})
1733+
// []int{1, 3, 4, 5}, []int{6}
1734+
1735+
left, right := lo.Difference([]int{0, 1, 2, 3, 4, 5}, []int{0, 1, 2, 3, 4, 5})
1736+
// []int{}, []int{}
1737+
```
1738+
17231739
### Union
17241740

17251741
Returns all distinct elements from given collections. Result will not change the order of elements relatively.

intersect.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,38 @@ func Difference[T comparable](list1 []T, list2 []T) ([]T, []T) {
141141
return left, right
142142
}
143143

144+
// Symmetric difference returns the elements presents in one collection
145+
// but not in the other
146+
// Order is not preserved
147+
func SymmetricDifference[T comparable](list1 []T, list2 []T) []T {
148+
diff := []T{}
149+
150+
seenLeft := map[T]struct{}{}
151+
seenRight := map[T]struct{}{}
152+
153+
for _, elem := range list1 {
154+
seenLeft[elem] = struct{}{}
155+
}
156+
157+
for _, elem := range list2 {
158+
seenRight[elem] = struct{}{}
159+
}
160+
161+
for _, elem := range list1 {
162+
if _, ok := seenRight[elem]; !ok {
163+
diff = append(diff, elem)
164+
}
165+
}
166+
167+
for _, elem := range list2 {
168+
if _, ok := seenLeft[elem]; !ok {
169+
diff = append(diff, elem)
170+
}
171+
}
172+
173+
return diff
174+
}
175+
144176
// Union returns all distinct elements from given collections.
145177
// result returns will not change the order of elements relatively.
146178
func Union[T comparable](lists ...[]T) []T {

intersect_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,21 @@ func TestDifference(t *testing.T) {
206206
is.Equal(right3, []int{})
207207
}
208208

209+
func TestSymmetricDifference(t *testing.T) {
210+
t.Parallel()
211+
is := assert.New(t)
212+
213+
diff1 := SymmetricDifference([]int{0, 1, 2, 3, 4, 5}, []int{0, 2, 6})
214+
is.ElementsMatch(diff1, []int{1, 3, 4, 5, 6})
215+
216+
diff2 := SymmetricDifference([]int{1, 2, 3, 4, 5}, []int{0, 6})
217+
is.ElementsMatch(diff2, []int{0, 1, 2, 3, 4, 5, 6})
218+
219+
diff3 := SymmetricDifference([]int{0, 1, 2, 3, 4, 5}, []int{0, 1, 2, 3, 4, 5})
220+
is.ElementsMatch(diff3, []int{})
221+
}
222+
223+
209224
func TestUnion(t *testing.T) {
210225
t.Parallel()
211226
is := assert.New(t)

0 commit comments

Comments
 (0)