mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-04 12:52:28 +08:00
feat: add FilterConcurrent
This commit is contained in:
@@ -45,6 +45,7 @@ import (
|
|||||||
- [Equal](#Equal)
|
- [Equal](#Equal)
|
||||||
- [EqualWith](#EqualWith)
|
- [EqualWith](#EqualWith)
|
||||||
- [Filter](#Filter)
|
- [Filter](#Filter)
|
||||||
|
- [FilterConcurrent](#FilterConcurrent)
|
||||||
- [Find<sup>deprecated</sup>](#Find)
|
- [Find<sup>deprecated</sup>](#Find)
|
||||||
- [FindBy](#FindBy)
|
- [FindBy](#FindBy)
|
||||||
- [FindLast<sup>deprecated</sup>](#FindLast)
|
- [FindLast<sup>deprecated</sup>](#FindLast)
|
||||||
@@ -901,6 +902,40 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="FilterConcurrent">FilterConcurrent</span>
|
||||||
|
|
||||||
|
<p>对slice并发执行filter操作。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func FilterConcurrent[T any](slice []T, numOfThreads int, predicate func(index int, item T) bool) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5}
|
||||||
|
|
||||||
|
isEven := func(i, num int) bool {
|
||||||
|
return num%2 == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
result := slice.FilterConcurrent(nums, 2, isEven)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [2 4]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Find">Find</span>
|
### <span id="Find">Find</span>
|
||||||
|
|
||||||
<p>遍历slice的元素,返回第一个通过predicate函数真值测试的元素</p>
|
<p>遍历slice的元素,返回第一个通过predicate函数真值测试的元素</p>
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import (
|
|||||||
- [EqualWith](#EqualWith)
|
- [EqualWith](#EqualWith)
|
||||||
- [Every](#Every)
|
- [Every](#Every)
|
||||||
- [Filter](#Filter)
|
- [Filter](#Filter)
|
||||||
|
- [FilterConcurrent](#FilterConcurrent)
|
||||||
- [Find<sup>deprecated</sup>](#Find)
|
- [Find<sup>deprecated</sup>](#Find)
|
||||||
- [FindBy](#FindBy)
|
- [FindBy](#FindBy)
|
||||||
- [FindLast<sup>deprecated</sup>](#FindLast)
|
- [FindLast<sup>deprecated</sup>](#FindLast)
|
||||||
@@ -899,6 +900,40 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="FilterConcurrent">FilterConcurrent</span>
|
||||||
|
|
||||||
|
<p>Applies the provided filter function `predicate` to each element of the input slice concurrently.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func FilterConcurrent[T any](slice []T, numOfThreads int, predicate func(index int, item T) bool) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5}
|
||||||
|
|
||||||
|
isEven := func(i, num int) bool {
|
||||||
|
return num%2 == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
result := slice.FilterConcurrent(nums, 2, isEven)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [2 4]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="Find">Find</span>
|
### <span id="Find">Find</span>
|
||||||
|
|
||||||
<p>Iterates over elements of slice, returning the first one that passes a truth test on function.</p>
|
<p>Iterates over elements of slice, returning the first one that passes a truth test on function.</p>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MapConcurrent applies the iteratee function to each item in the slice by concrrent.
|
// MapConcurrent applies the iteratee function to each item in the slice concurrently.
|
||||||
// Play: todo
|
// Play: todo
|
||||||
func MapConcurrent[T any, U any](slice []T, numOfThreads int, iteratee func(index int, item T) U) []U {
|
func MapConcurrent[T any, U any](slice []T, numOfThreads int, iteratee func(index int, item T) U) []U {
|
||||||
result := make([]U, len(slice))
|
result := make([]U, len(slice))
|
||||||
@@ -35,6 +35,35 @@ func MapConcurrent[T any, U any](slice []T, numOfThreads int, iteratee func(inde
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FilterConcurrent applies the provided filter function `predicate` to each element of the input slice concurrently.
|
||||||
|
// Play: todo
|
||||||
|
func FilterConcurrent[T any](slice []T, numOfThreads int, predicate func(index int, item T) bool) []T {
|
||||||
|
result := make([]T, 0)
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
workerChan := make(chan struct{}, numOfThreads)
|
||||||
|
|
||||||
|
for index, item := range slice {
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
workerChan <- struct{}{}
|
||||||
|
|
||||||
|
go func(i int, v T) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
if predicate(i, v) {
|
||||||
|
result = append(result, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
<-workerChan
|
||||||
|
}(index, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// UniqueByParallel removes duplicate elements from the slice by parallel
|
// UniqueByParallel removes duplicate elements from the slice by parallel
|
||||||
// The comparator function is used to compare the elements
|
// The comparator function is used to compare the elements
|
||||||
// The numOfThreads parameter specifies the number of threads to use
|
// The numOfThreads parameter specifies the number of threads to use
|
||||||
|
|||||||
@@ -247,6 +247,21 @@ func ExampleFilter() {
|
|||||||
// [2 4]
|
// [2 4]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleFilterConcurrent() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5}
|
||||||
|
|
||||||
|
isEven := func(i, num int) bool {
|
||||||
|
return num%2 == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
result := FilterConcurrent(nums, 2, isEven)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [2 4]
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleCount() {
|
func ExampleCount() {
|
||||||
nums := []int{1, 2, 3, 3, 4}
|
nums := []int{1, 2, 3, 3, 4}
|
||||||
|
|
||||||
|
|||||||
@@ -1542,3 +1542,29 @@ func TestMapConcurrent(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFilterConcurrent(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestFilterConcurrent")
|
||||||
|
|
||||||
|
t.Run("empty slice", func(t *testing.T) {
|
||||||
|
actual := FilterConcurrent([]int{}, 4, func(_, n int) bool { return n != 0 })
|
||||||
|
assert.Equal([]int{}, actual)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("single thread", func(t *testing.T) {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
|
expected := []int{4, 5, 6}
|
||||||
|
actual := FilterConcurrent(nums, 1, func(_, n int) bool { return n > 3 })
|
||||||
|
assert.Equal(expected, actual)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("multiple threads", func(t *testing.T) {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
|
expected := []int{4, 5, 6}
|
||||||
|
actual := FilterConcurrent(nums, 4, func(_, n int) bool { return n > 3 })
|
||||||
|
assert.Equal(expected, actual)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user