diff --git a/README.md b/README.md index 886e399..06cb27c 100644 --- a/README.md +++ b/README.md @@ -469,6 +469,8 @@ Some utilities that are convenient when working with slices. - `slice.Filter[A any](as []A, p func(a A) bool) (res []A)` - `slice.FilterNot[A any](as []A, p func(a A) bool) (res []A)` - same as `Filter`, but inverses the predicate `p`. - `slice.Remove[A comparable](as []A, r []A) (res []A)` - Remove removes any elements in r from as. +- `slice.Intersection[A comparable](as []A, as2 []A) (res []A)` - Intersection leaves only elements that are both in as and as2. +- `slice.Union[A comparable](as []A, as2 []A) (res []A)` - Union returns elements that are either in as or in as2. - `slice.Partition[A any](as []A, p fun.Predicate[A]) (resT []A, resF []A)` - Partition separates elements in as according to the predicate. - `slice.Exists[A any](p fun.Predicate[A]) fun.Predicate[[]A]` - Exists returns a predicate on slices. The predicate is true if there is an element that satisfy the given element-wise predicate. It's false for an empty slice. - `slice.Forall[A any](p fun.Predicate[A]) fun.Predicate[[]A]` - Forall returns a predicate on slices. The predicate is true if all elements satisfy the given element-wise predicate. It's true for an empty slice. diff --git a/slice/slice.go b/slice/slice.go index a490f63..febea7c 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -286,3 +286,15 @@ func Remove[A comparable](as []A, r []A) (res []A) { sr := ToSet(r) return FilterNot(as, set.Contains(sr)) } + +// Intersection leaves only elements that are both in as and as2. +func Intersection[A comparable](as []A, as2 []A) (res []A) { + sr := ToSet(as2) + return Filter(as, set.Contains(sr)) +} + +// Union returns elements that are either in as or in as2. +func Union[A comparable](as []A, as2 []A) (res []A) { + sr := ToSet(as) + return append(as, FilterNot(as2, set.Contains(sr))...) +} diff --git a/slice/slice_test.go b/slice/slice_test.go index 02d881f..d00080e 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -126,3 +126,17 @@ func TestRemove(t *testing.T) { znats510 := slice.Range(5, 10) assert.ElementsMatch(t, znats510, slice.Remove(znats10, znats5)) } + +func TestIntersection(t *testing.T) { + znats10 := slice.Range(0, 10) + znats515 := slice.Range(5, 15) + znats5 := slice.Range(5, 10) + assert.ElementsMatch(t, znats5, slice.Intersection(znats10, znats515)) +} + +func TestUnion(t *testing.T) { + znats10 := slice.Range(0, 10) + znats515 := slice.Range(5, 15) + znats15 := slice.Range(0, 15) + assert.ElementsMatch(t, znats15, slice.Union(znats10, znats515)) +}