Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Adding the equivalent of checking if two slices are the same #498

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ Supported intersection helpers:
- [ContainsBy](#containsby)
- [Every](#every)
- [EveryBy](#everyby)
- [Equivalent](#equivalent)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have to fix this

- [Some](#some)
- [SomeBy](#someby)
- [None](#none)
Expand Down Expand Up @@ -1947,6 +1948,16 @@ b := EveryBy([]int{1, 2, 3, 4}, func(x int) bool {
// true
```

### EqualUnordered

Returns true if the subset has the same elements and the same number of each element as the collection.
Unlike slices.Equal(), which returns effected by order, Equivalent does not care about the order of the elements.

```go
b := EqualUnordered([]int{0, 1, 1, 3, 0, 0}, []int{0, 1, 3, 0, 1, 0})
// true
```

### Some

Returns true if at least 1 element of a subset is contained into a collection.
Expand Down
21 changes: 21 additions & 0 deletions intersect.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,27 @@ func EveryBy[T any](collection []T, predicate func(item T) bool) bool {
return true
}

// EqualUnordered returns true if the subset has the same elements and the same number of each element as the collection.
// Unlike slices.Equal(), which returns effected by order, EqualUnordered does not care about the order of the elements.
func EqualUnordered[T comparable, Slice ~[]T](collection, subset Slice) bool {
l := len(collection)
if l != len(subset) {
return false
}

var m = make(map[T]int, l)
for i := 0; i < l; i++ {
m[collection[i]] += 1
m[subset[i]] -= 1
}
for _, v := range m {
if v != 0 {
return false
}
}
return true
}

// Some returns true if at least 1 element of a subset is contained into a collection.
// If the subset is empty Some returns false.
func Some[T comparable](collection []T, subset []T) bool {
Expand Down
23 changes: 23 additions & 0 deletions intersect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,29 @@ func TestEveryBy(t *testing.T) {
is.True(result4)
}

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

result1 := EqualUnordered([]int{0, 1, 2, 3, 4, 5}, []int{0, 1, 2, 3, 4, 5})
is.True(result1)

result2 := EqualUnordered([]int{2, 3, 4, 5, 0, 1}, []int{0, 1, 2, 3, 4, 5})
is.True(result2)

result3 := EqualUnordered([]int{0, 1, 1, 3, 0, 0}, []int{0, 1, 3, 0, 1, 0})
is.True(result3)

result4 := EqualUnordered([]int{0, 1, 2, 3, 4}, []int{0, 1, 2, 3, 4, 5})
is.False(result4)

result5 := EqualUnordered([]int{0, 1, 2, 3, 4, 6}, []int{0, 1, 2, 3, 4, 5})
is.False(result5)

result6 := EqualUnordered([]int{0, 1, 1, 1, 1, 1}, []int{0, 0, 1, 1, 1, 1})
is.False(result6)
}

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