Skip to content

Commit

Permalink
add intersect.SymmetricDifference
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrienPensart committed Jan 18, 2024
1 parent 71d8341 commit 65a254e
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
16 changes: 16 additions & 0 deletions README.md
Expand Up @@ -180,6 +180,7 @@ Supported intersection helpers:
- [NoneBy](#noneby)
- [Intersect](#intersect)
- [Difference](#difference)
- [SymmetricDifference](#symmetric_difference)
- [Union](#union)
- [Without](#without)
- [WithoutEmpty](#withoutempty)
Expand Down Expand Up @@ -1720,6 +1721,21 @@ left, right := lo.Difference([]int{0, 1, 2, 3, 4, 5}, []int{0, 1, 2, 3, 4, 5})
// []int{}, []int{}
```

### SymmetricDifference

Returns the symmetric difference between two collections.

Returns all elements which are in either of the collections but not in both.
Does not preserve order of elements.

```go
diff := SymmetricDifference([]int{0, 1, 2, 3, 4, 5}, []int{0, 2, 6})
// []int{1, 3, 4, 5, 6}

diff := SymmetricDifference([]int{0, 1, 2, 3, 4, 5}, []int{0, 1, 2, 3, 4, 5})
// []int{}
```

### Union

Returns all distinct elements from given collections. Result will not change the order of elements relatively.
Expand Down
32 changes: 32 additions & 0 deletions intersect.go
Expand Up @@ -141,6 +141,38 @@ func Difference[T comparable](list1 []T, list2 []T) ([]T, []T) {
return left, right
}

// Symmetric difference returns the elements presents in one collection
// but not in the other
// Order is not preserved
func SymmetricDifference[T comparable](list1 []T, list2 []T) []T {
diff := []T{}

seenLeft := map[T]struct{}{}
seenRight := map[T]struct{}{}

for _, elem := range list1 {
seenLeft[elem] = struct{}{}
}

for _, elem := range list2 {
seenRight[elem] = struct{}{}
}

for _, elem := range list1 {
if _, ok := seenRight[elem]; !ok {
diff = append(diff, elem)
}
}

for _, elem := range list2 {
if _, ok := seenLeft[elem]; !ok {
diff = append(diff, elem)
}
}

return diff
}

// Union returns all distinct elements from given collections.
// result returns will not change the order of elements relatively.
func Union[T comparable](lists ...[]T) []T {
Expand Down
15 changes: 15 additions & 0 deletions intersect_test.go
Expand Up @@ -206,6 +206,21 @@ func TestDifference(t *testing.T) {
is.Equal(right3, []int{})
}

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

diff1 := SymmetricDifference([]int{0, 1, 2, 3, 4, 5}, []int{0, 2, 6})
is.ElementsMatch(diff1, []int{1, 3, 4, 5, 6})

diff2 := SymmetricDifference([]int{1, 2, 3, 4, 5}, []int{0, 6})
is.ElementsMatch(diff2, []int{0, 1, 2, 3, 4, 5, 6})

diff3 := SymmetricDifference([]int{0, 1, 2, 3, 4, 5}, []int{0, 1, 2, 3, 4, 5})
is.ElementsMatch(diff3, []int{})
}


func TestUnion(t *testing.T) {
t.Parallel()
is := assert.New(t)
Expand Down

0 comments on commit 65a254e

Please sign in to comment.