diff --git a/docs/api/packages/slice.md b/docs/api/packages/slice.md index 00080ab..fbfd6ac 100644 --- a/docs/api/packages/slice.md +++ b/docs/api/packages/slice.md @@ -44,6 +44,7 @@ import ( - [Every](#Every) - [Equal](#Equal) - [EqualWith](#EqualWith) +- [EqualUnordered](#EqualUnordered) - [Filter](#Filter) - [FilterConcurrent](#FilterConcurrent) - [Finddeprecated](#Find) @@ -874,6 +875,37 @@ func main() { } ``` +### EqualUnordered + +

检查两个切片是否相等,元素数量相同,值相等,不考虑元素顺序。

+ +函数签名: + +```go +func EqualUnordered[T comparable](slice1, slice2 []T) bool +``` + +示例:[运行](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.EqualUnordered([]int{1, 2, 3}, []int{3, 2, 1}) + result2 := slice.EqualUnordered([]int{1, 2, 3}, []int{4, 5, 6}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + ### Filter

返回切片中通过predicate函数真值测试的所有元素

diff --git a/docs/en/api/packages/slice.md b/docs/en/api/packages/slice.md index e26a1ed..6e5e5b7 100644 --- a/docs/en/api/packages/slice.md +++ b/docs/en/api/packages/slice.md @@ -43,6 +43,7 @@ import ( - [DropRightWhile](#DropRightWhile) - [Equal](#Equal) - [EqualWith](#EqualWith) +- [EqualUnordered](#EqualUnordered) - [Every](#Every) - [Filter](#Filter) - [FilterConcurrent](#FilterConcurrent) @@ -839,6 +840,37 @@ func main() { } ``` +### EqualUnordered + +

Checks if two slices are equal: the same length and all elements' value are equal (unordered).

+ +Signature: + +```go +func EqualUnordered[T comparable](slice1, slice2 []T) bool +``` + +Example:[运行](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/slice" +) + +func main() { + result1 := slice.EqualUnordered([]int{1, 2, 3}, []int{3, 2, 1}) + result2 := slice.EqualUnordered([]int{1, 2, 3}, []int{4, 5, 6}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} +``` + ### Every

Return true if all of the values in the slice pass the predicate function.

diff --git a/slice/slice.go b/slice/slice.go index 4208eba..de2f119 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -220,6 +220,28 @@ func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) boo return true } +// EqualUnordered checks if two slices are equal: the same length and all elements' value are equal (unordered). +// Play: todo +func EqualUnordered[T comparable](slice1, slice2 []T) bool { + if len(slice1) != len(slice2) { + return false + } + + seen := make(map[T]int) + for _, v := range slice1 { + seen[v]++ + } + + for _, v := range slice2 { + if seen[v] == 0 { + return false + } + seen[v]-- + } + + return true +} + // Every return true if all of the values in the slice pass the predicate function. // Play: https://go.dev/play/p/R8U6Sl-j8cD func Every[T any](slice []T, predicate func(index int, item T) bool) bool { diff --git a/slice/slice_example_test.go b/slice/slice_example_test.go index 81ff39f..3324a02 100644 --- a/slice/slice_example_test.go +++ b/slice/slice_example_test.go @@ -1300,3 +1300,15 @@ func ExampleConcatBy() { // Alice | Bob | Charlie // 90 } + +func ExampleEqualUnordered() { + result1 := EqualUnordered([]int{1, 2, 3}, []int{3, 2, 1}) + result2 := EqualUnordered([]int{1, 2, 3}, []int{4, 5, 6}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // true + // false +} diff --git a/slice/slice_test.go b/slice/slice_test.go index 9191c73..6e9a5c3 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -1926,3 +1926,25 @@ func TestConcatBy(t *testing.T) { assert.Equal(90, result.Age) }) } + +func TestEqualUnordered(t *testing.T) { + t.Parallel() + + assert := internal.NewAssert(t, "TestEqualUnordered") + + tests := []struct { + slice1, slice2 []int + expected bool + }{ + {[]int{}, []int{}, true}, + {[]int{1, 2, 3}, []int{1, 2, 3}, true}, + {[]int{1, 2, 3}, []int{3, 2, 1}, true}, + {[]int{1, 2, 3}, []int{1, 2, 3, 4}, false}, + {[]int{1, 2, 3}, []int{1, 2}, false}, + {[]int{1, 2, 3}, []int{1, 2, 4}, false}, + } + + for _, test := range tests { + assert.Equal(test.expected, EqualUnordered(test.slice1, test.slice2)) + } +}