1
0
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:
dudaodong
2024-08-14 11:19:10 +08:00
parent 7f78a6b11e
commit a360372aa9
5 changed files with 141 additions and 1 deletions

View File

@@ -8,7 +8,7 @@ import (
"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
func MapConcurrent[T any, U any](slice []T, numOfThreads int, iteratee func(index int, item T) U) []U {
result := make([]U, len(slice))
@@ -35,6 +35,35 @@ func MapConcurrent[T any, U any](slice []T, numOfThreads int, iteratee func(inde
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
// The comparator function is used to compare the elements
// The numOfThreads parameter specifies the number of threads to use

View File

@@ -247,6 +247,21 @@ func ExampleFilter() {
// [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() {
nums := []int{1, 2, 3, 3, 4}

View File

@@ -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)
})
}