mirror of
https://github.com/duke-git/lancet.git
synced 2026-03-01 00:35:28 +08:00
Compare commits
2 Commits
d4b425e39c
...
ab89f0aee1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab89f0aee1 | ||
|
|
1f64e02df4 |
@@ -44,6 +44,7 @@ import (
|
|||||||
- [Every](#Every)
|
- [Every](#Every)
|
||||||
- [Equal](#Equal)
|
- [Equal](#Equal)
|
||||||
- [EqualWith](#EqualWith)
|
- [EqualWith](#EqualWith)
|
||||||
|
- [EqualUnordered](#EqualUnordered)
|
||||||
- [Filter](#Filter)
|
- [Filter](#Filter)
|
||||||
- [FilterConcurrent](#FilterConcurrent)
|
- [FilterConcurrent](#FilterConcurrent)
|
||||||
- [Find<sup>deprecated</sup>](#Find)
|
- [Find<sup>deprecated</sup>](#Find)
|
||||||
@@ -874,6 +875,37 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="EqualUnordered">EqualUnordered</span>
|
||||||
|
|
||||||
|
<p>检查两个切片是否相等,元素数量相同,值相等,不考虑元素顺序。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func EqualUnordered[T comparable](slice1, slice2 []T) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```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
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Filter">Filter</span>
|
### <span id="Filter">Filter</span>
|
||||||
|
|
||||||
<p>返回切片中通过predicate函数真值测试的所有元素</p>
|
<p>返回切片中通过predicate函数真值测试的所有元素</p>
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import (
|
|||||||
- [DropRightWhile](#DropRightWhile)
|
- [DropRightWhile](#DropRightWhile)
|
||||||
- [Equal](#Equal)
|
- [Equal](#Equal)
|
||||||
- [EqualWith](#EqualWith)
|
- [EqualWith](#EqualWith)
|
||||||
|
- [EqualUnordered](#EqualUnordered)
|
||||||
- [Every](#Every)
|
- [Every](#Every)
|
||||||
- [Filter](#Filter)
|
- [Filter](#Filter)
|
||||||
- [FilterConcurrent](#FilterConcurrent)
|
- [FilterConcurrent](#FilterConcurrent)
|
||||||
@@ -839,6 +840,37 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="EqualUnordered">EqualUnordered</span>
|
||||||
|
|
||||||
|
<p>Checks if two slices are equal: the same length and all elements' value are equal (unordered).</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func EqualUnordered[T comparable](slice1, slice2 []T) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```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
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Every">Every</span>
|
### <span id="Every">Every</span>
|
||||||
|
|
||||||
<p>Return true if all of the values in the slice pass the predicate function.</p>
|
<p>Return true if all of the values in the slice pass the predicate function.</p>
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/validator"
|
"github.com/duke-git/lancet/v2/validator"
|
||||||
|
"golang.org/x/text/encoding/simplifiedchinese"
|
||||||
|
"golang.org/x/text/transform"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FileReader is a reader supporting offset seeking and reading one
|
// FileReader is a reader supporting offset seeking and reading one
|
||||||
@@ -422,8 +424,15 @@ func UnZip(zipFile string, destPath string) error {
|
|||||||
defer zipReader.Close()
|
defer zipReader.Close()
|
||||||
|
|
||||||
for _, f := range zipReader.File {
|
for _, f := range zipReader.File {
|
||||||
|
decodeName := f.Name
|
||||||
|
if f.Flags == 0 {
|
||||||
|
i := bytes.NewReader([]byte(f.Name))
|
||||||
|
decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder())
|
||||||
|
content, _ := io.ReadAll(decoder)
|
||||||
|
decodeName = string(content)
|
||||||
|
}
|
||||||
// issue#62: fix ZipSlip bug
|
// issue#62: fix ZipSlip bug
|
||||||
path, err := safeFilepathJoin(destPath, f.Name)
|
path, err := safeFilepathJoin(destPath, decodeName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,6 +220,28 @@ func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) boo
|
|||||||
return true
|
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.
|
// Every return true if all of the values in the slice pass the predicate function.
|
||||||
// Play: https://go.dev/play/p/R8U6Sl-j8cD
|
// Play: https://go.dev/play/p/R8U6Sl-j8cD
|
||||||
func Every[T any](slice []T, predicate func(index int, item T) bool) bool {
|
func Every[T any](slice []T, predicate func(index int, item T) bool) bool {
|
||||||
|
|||||||
@@ -1300,3 +1300,15 @@ func ExampleConcatBy() {
|
|||||||
// Alice | Bob | Charlie
|
// Alice | Bob | Charlie
|
||||||
// 90
|
// 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
|
||||||
|
}
|
||||||
|
|||||||
@@ -1926,3 +1926,25 @@ func TestConcatBy(t *testing.T) {
|
|||||||
assert.Equal(90, result.Age)
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user