mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-15 10:12:29 +08:00
feat: add MapConcurrent
This commit is contained in:
@@ -1451,7 +1451,7 @@ func main() {
|
|||||||
|
|
||||||
### <span id="Map">Map</span>
|
### <span id="Map">Map</span>
|
||||||
|
|
||||||
<p>对slice中的每个元素执行map函数以创建一个新切片</p>
|
<p>对slice中的每个元素执行map函数以创建一个新切片。</p>
|
||||||
|
|
||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
@@ -1483,6 +1483,36 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="MapConcurrent">MapConcurrent</span>
|
||||||
|
|
||||||
|
<p>对slice并发执行map操作。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func MapConcurrent[T any, U any](slice []T, numOfThreads int, iteratee func(index int, item T) U) []U
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
|
|
||||||
|
result := slice.MapConcurrent(nums, 4, func(_, n int) int { return n * n })
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [1 4 9 16 25 36]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="FilterMap">FilterMap</span>
|
### <span id="FilterMap">FilterMap</span>
|
||||||
|
|
||||||
<p>返回一个将filter和map操作应用于给定切片的切片。 iteratee回调函数应该返回两个值:1,结果值。2,结果值是否应该被包含在返回的切片中。</p>
|
<p>返回一个将filter和map操作应用于给定切片的切片。 iteratee回调函数应该返回两个值:1,结果值。2,结果值是否应该被包含在返回的切片中。</p>
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ import (
|
|||||||
- [IndexOf](#IndexOf)
|
- [IndexOf](#IndexOf)
|
||||||
- [LastIndexOf](#LastIndexOf)
|
- [LastIndexOf](#LastIndexOf)
|
||||||
- [Map](#Map)
|
- [Map](#Map)
|
||||||
|
- [MapConcurrent](#MapConcurrent)
|
||||||
- [FilterMap](#FilterMap)
|
- [FilterMap](#FilterMap)
|
||||||
- [FlatMap](#FlatMap)
|
- [FlatMap](#FlatMap)
|
||||||
- [Merge](#Merge)
|
- [Merge](#Merge)
|
||||||
@@ -1481,6 +1482,36 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="MapConcurrent">MapConcurrent</span>
|
||||||
|
|
||||||
|
<p>Applies the iteratee function to each item in the slice by concrrent.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func MapConcurrent[T any, U any](slice []T, numOfThreads int, iteratee func(index int, item T) U) []U
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
|
|
||||||
|
result := slice.MapConcurrent(nums, 4, func(_, n int) int { return n * n })
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [1 4 9 16 25 36]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="FilterMap">FilterMap</span>
|
### <span id="FilterMap">FilterMap</span>
|
||||||
|
|
||||||
<p>Returns a slice which apply both filtering and mapping to the given slice. iteratee callback function should returntwo values: 1, mapping result. 2, whether the result element should be included or not.</p>
|
<p>Returns a slice which apply both filtering and mapping to the given slice. iteratee callback function should returntwo values: 1, mapping result. 2, whether the result element should be included or not.</p>
|
||||||
|
|||||||
@@ -1139,6 +1139,7 @@ func ExampleRandom() {
|
|||||||
if idx >= 0 && idx < len(nums) && Contain(nums, val) {
|
if idx >= 0 && idx < len(nums) && Contain(nums, val) {
|
||||||
fmt.Println("okk")
|
fmt.Println("okk")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// okk
|
// okk
|
||||||
}
|
}
|
||||||
@@ -1148,6 +1149,7 @@ func ExampleSetToDefaultIf() {
|
|||||||
modifiedStrs, count := SetToDefaultIf(strs, func(s string) bool { return "a" == s })
|
modifiedStrs, count := SetToDefaultIf(strs, func(s string) bool { return "a" == s })
|
||||||
fmt.Println(modifiedStrs)
|
fmt.Println(modifiedStrs)
|
||||||
fmt.Println(count)
|
fmt.Println(count)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// [ b c d ]
|
// [ b c d ]
|
||||||
// 3
|
// 3
|
||||||
@@ -1170,6 +1172,7 @@ func ExampleRightPadding() {
|
|||||||
nums := []int{1, 2, 3, 4, 5}
|
nums := []int{1, 2, 3, 4, 5}
|
||||||
padded := RightPadding(nums, 0, 3)
|
padded := RightPadding(nums, 0, 3)
|
||||||
fmt.Println(padded)
|
fmt.Println(padded)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// [1 2 3 4 5 0 0 0]
|
// [1 2 3 4 5 0 0 0]
|
||||||
}
|
}
|
||||||
@@ -1178,6 +1181,7 @@ func ExampleLeftPadding() {
|
|||||||
nums := []int{1, 2, 3, 4, 5}
|
nums := []int{1, 2, 3, 4, 5}
|
||||||
padded := LeftPadding(nums, 0, 3)
|
padded := LeftPadding(nums, 0, 3)
|
||||||
fmt.Println(padded)
|
fmt.Println(padded)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// [0 0 0 1 2 3 4 5]
|
// [0 0 0 1 2 3 4 5]
|
||||||
}
|
}
|
||||||
@@ -1190,6 +1194,17 @@ func ExampleUniqueByParallel() {
|
|||||||
result := UniqueByParallel(nums, numOfThreads, comparator)
|
result := UniqueByParallel(nums, numOfThreads, comparator)
|
||||||
|
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// [1 2 3 4 5 6 7]
|
// [1 2 3 4 5 6 7]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleMapConcurrent() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
|
result := MapConcurrent(nums, 4, func(_, n int) int { return n * n })
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [1 4 9 16 25 36]
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,33 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MapConcurrent applies the iteratee function to each item in the slice by concrrent.
|
||||||
|
// 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))
|
||||||
|
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()
|
||||||
|
|
||||||
|
result[i] = iteratee(i, 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
|
||||||
|
|||||||
@@ -1516,3 +1516,29 @@ func TestUniqueByParallel(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal([]int{1, 2, 3, 4, 5, 6, 7}, result)
|
assert.Equal([]int{1, 2, 3, 4, 5, 6, 7}, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMapConcurrent(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestMapConcurrent")
|
||||||
|
|
||||||
|
t.Run("empty slice", func(t *testing.T) {
|
||||||
|
actual := MapConcurrent([]int{}, 4, func(_, n int) int { return n * n })
|
||||||
|
assert.Equal([]int{}, actual)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("single thread", func(t *testing.T) {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
|
expected := []int{1, 4, 9, 16, 25, 36}
|
||||||
|
actual := MapConcurrent(nums, 1, func(_, n int) int { return n * n })
|
||||||
|
assert.Equal(expected, actual)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("multiple threads", func(t *testing.T) {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
|
expected := []int{1, 4, 9, 16, 25, 36}
|
||||||
|
actual := MapConcurrent(nums, 4, func(_, n int) int { return n * n })
|
||||||
|
assert.Equal(expected, actual)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user