mirror of
https://github.com/duke-git/lancet.git
synced 2026-03-01 00:35:28 +08:00
Compare commits
4 Commits
7b4e060f85
...
c0b200f846
| Author | SHA1 | Date | |
|---|---|---|---|
| c0b200f846 | |||
| 305847993c | |||
| f5d70728c3 | |||
| c2a5335bc6 |
@@ -26,6 +26,7 @@ import (
|
|||||||
- [RandInt](#RandInt)
|
- [RandInt](#RandInt)
|
||||||
- [RandString](#RandString)
|
- [RandString](#RandString)
|
||||||
- [RandFromGivenSlice](#RandFromGivenSlice)
|
- [RandFromGivenSlice](#RandFromGivenSlice)
|
||||||
|
- [RandSliceFromGivenSlice](#RandSliceFromGivenSlice)
|
||||||
- [RandUpper](#RandUpper)
|
- [RandUpper](#RandUpper)
|
||||||
- [RandLower](#RandLower)
|
- [RandLower](#RandLower)
|
||||||
- [RandNumeral](#RandNumeral)
|
- [RandNumeral](#RandNumeral)
|
||||||
@@ -150,6 +151,33 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="RandSliceFromGivenSlice">RandSliceFromGivenSlice</span>
|
||||||
|
|
||||||
|
<p>从给定切片中生成长度为 num 的随机切片</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandSliceFromGivenSlice[T any](slice []T, num int, repeatable bool) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行]()</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
goods := []string{"apple", "banana", "cherry", "elderberry", "fig", "grape", "honeydew", "kiwi", "lemon","mango", "nectarine", "orange"}
|
||||||
|
chosen3goods := random.RandSliceFromGivenSlice(goods, 3, false)
|
||||||
|
fmt.Println(chosen3goods)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="RandUpper">RandUpper</span>
|
### <span id="RandUpper">RandUpper</span>
|
||||||
|
|
||||||
<p>生成给定长度的随机大写字母字符串</p>
|
<p>生成给定长度的随机大写字母字符串</p>
|
||||||
|
|||||||
+83
-11
@@ -53,6 +53,7 @@ import (
|
|||||||
- [Flatten](#Flatten)
|
- [Flatten](#Flatten)
|
||||||
- [FlattenDeep](#FlattenDeep)
|
- [FlattenDeep](#FlattenDeep)
|
||||||
- [ForEach](#ForEach)
|
- [ForEach](#ForEach)
|
||||||
|
- [ForEachConcurrent](#ForEachConcurrent)
|
||||||
- [ForEachWithBreak](#ForEachWithBreak)
|
- [ForEachWithBreak](#ForEachWithBreak)
|
||||||
- [GroupBy](#GroupBy)
|
- [GroupBy](#GroupBy)
|
||||||
- [GroupWith](#GroupWith)
|
- [GroupWith](#GroupWith)
|
||||||
@@ -69,6 +70,7 @@ import (
|
|||||||
- [Merge](#Merge)
|
- [Merge](#Merge)
|
||||||
- [Reverse](#Reverse)
|
- [Reverse](#Reverse)
|
||||||
- [Reduce<sup>deprecated</sup>](#Reduce)
|
- [Reduce<sup>deprecated</sup>](#Reduce)
|
||||||
|
- [ReduceConcurrent](#ReduceConcurrent)
|
||||||
- [ReduceBy](#ReduceBy)
|
- [ReduceBy](#ReduceBy)
|
||||||
- [ReduceRight](#ReduceRight)
|
- [ReduceRight](#ReduceRight)
|
||||||
- [Replace](#Replace)
|
- [Replace](#Replace)
|
||||||
@@ -909,7 +911,7 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func FilterConcurrent[T any](slice []T, numOfThreads int, predicate func(index int, item T) bool) []T
|
func FilterConcurrent[T any](slice []T, predicate func(index int, item T) bool, numThreads int) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
@@ -927,7 +929,7 @@ func main() {
|
|||||||
return num%2 == 0
|
return num%2 == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
result := slice.FilterConcurrent(nums, 2, isEven)
|
result := slice.FilterConcurrent(nums, isEven, 2)
|
||||||
|
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
|
|
||||||
@@ -1179,6 +1181,43 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ForEachConcurrent">ForEachConcurrent</span>
|
||||||
|
|
||||||
|
<p>对slice并发执行foreach操作。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ForEachConcurrent[T any](slice []T, iteratee func(index int, item T), numThreads int)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行]()</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
|
|
||||||
|
result := make([]int, len(nums))
|
||||||
|
|
||||||
|
addOne := func(index int, value int) {
|
||||||
|
result[index] = value + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
slice.ForEachConcurrent(nums, addOne, 4)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [2 3 4 5 6 7 8 9]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="ForEachWithBreak">ForEachWithBreak</span>
|
### <span id="ForEachWithBreak">ForEachWithBreak</span>
|
||||||
|
|
||||||
<p>遍历切片的元素并为每个元素调用iteratee函数,当iteratee函数返回false时,终止遍历。</p>
|
<p>遍历切片的元素并为每个元素调用iteratee函数,当iteratee函数返回false时,终止遍历。</p>
|
||||||
@@ -1527,7 +1566,7 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
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, iteratee func(index int, item T) U, numThreads int) []U
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
@@ -1540,13 +1579,15 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
nums := []int{1, 2, 3, 4, 5, 6}
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
|
|
||||||
result := slice.MapConcurrent(nums, 4, func(_, n int) int { return n * n })
|
result := slice.MapConcurrent(nums, func(_, n int) int {
|
||||||
|
return n * n
|
||||||
|
}, 4)
|
||||||
|
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// [1 4 9 16 25 36]
|
// [1 4 9 16 25 36]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1719,6 +1760,38 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ReduceConcurrent">ReduceConcurrent</span>
|
||||||
|
|
||||||
|
<p>对切片元素执行并发reduce操作。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReduceConcurrent[T any](slice []T, initial T, reducer func(index int, item T, agg T) T, numThreads int) T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行]()</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||||
|
|
||||||
|
result := slice.ReduceConcurrent(nums, 0, func(_ int, item, agg int) int {
|
||||||
|
return agg + item
|
||||||
|
}, 1)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 55
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="ReduceBy">ReduceBy</span>
|
### <span id="ReduceBy">ReduceBy</span>
|
||||||
|
|
||||||
<p>对切片元素执行reduce操作。</p>
|
<p>对切片元素执行reduce操作。</p>
|
||||||
@@ -2439,7 +2512,7 @@ func main() {
|
|||||||
<b>函数签名:</b>
|
<b>函数签名:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func UniqueByConcurrent[T comparable](slice []T, numOfThreads int, comparator func(item T, other T) bool) []T
|
func UniqueByConcurrent[T comparable](slice []T, comparator func(item T, other T) bool, numThreads int) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
@@ -2452,10 +2525,9 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
|
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
|
||||||
numOfThreads := 4
|
|
||||||
comparator := func(item int, other int) bool { return item == other }
|
comparator := func(item int, other int) bool { return item == other }
|
||||||
|
|
||||||
result := slice.UniqueByConcurrent(nums, numOfThreads, comparator)
|
result := slice.UniqueByConcurrent(nums, comparator, 4)
|
||||||
|
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
// Output:
|
// Output:
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import (
|
|||||||
- [RandBytes](#RandBytes)
|
- [RandBytes](#RandBytes)
|
||||||
- [RandInt](#RandInt)
|
- [RandInt](#RandInt)
|
||||||
- [RandString](#RandString)
|
- [RandString](#RandString)
|
||||||
|
- [RandFromGivenSlice](#RandFromGivenSlice)
|
||||||
|
- [RandSliceFromGivenSlice](#RandSliceFromGivenSlice)
|
||||||
- [RandUpper](#RandUpper)
|
- [RandUpper](#RandUpper)
|
||||||
- [RandLower](#RandLower)
|
- [RandLower](#RandLower)
|
||||||
- [RandNumeral](#RandNumeral)
|
- [RandNumeral](#RandNumeral)
|
||||||
@@ -148,6 +150,33 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="RandSliceFromGivenSlice">RandSliceFromGivenSlice</span>
|
||||||
|
|
||||||
|
<p>Generate a random slice of length num from given slice.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandSliceFromGivenSlice[T any](slice []T, num int, repeatable bool) []T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run]()</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
goods := []string{"apple", "banana", "cherry", "elderberry", "fig", "grape", "honeydew", "kiwi", "lemon", "mango", "nectarine", "orange"}
|
||||||
|
chosen3goods := random.RandSliceFromGivenSlice(goods, 3, false)
|
||||||
|
fmt.Println(chosen3goods)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="RandUpper">RandUpper</span>
|
### <span id="RandUpper">RandUpper</span>
|
||||||
|
|
||||||
<p>Generate a random upper case string</p>
|
<p>Generate a random upper case string</p>
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import (
|
|||||||
- [Flatten](#Flatten)
|
- [Flatten](#Flatten)
|
||||||
- [FlattenDeep](#FlattenDeep)
|
- [FlattenDeep](#FlattenDeep)
|
||||||
- [ForEach](#ForEach)
|
- [ForEach](#ForEach)
|
||||||
|
- [ForEachConcurrent](#ForEachConcurrent)
|
||||||
- [ForEachWithBreak](#ForEachWithBreak)
|
- [ForEachWithBreak](#ForEachWithBreak)
|
||||||
- [GroupBy](#GroupBy)
|
- [GroupBy](#GroupBy)
|
||||||
- [GroupWith](#GroupWith)
|
- [GroupWith](#GroupWith)
|
||||||
@@ -69,6 +70,7 @@ import (
|
|||||||
- [Merge](#Merge)
|
- [Merge](#Merge)
|
||||||
- [Reverse](#Reverse)
|
- [Reverse](#Reverse)
|
||||||
- [Reduce<sup>deprecated</sup>](#Reduce)
|
- [Reduce<sup>deprecated</sup>](#Reduce)
|
||||||
|
- [ReduceConcurrent](#ReduceConcurrent)
|
||||||
- [ReduceBy](#ReduceBy)
|
- [ReduceBy](#ReduceBy)
|
||||||
- [ReduceRight](#ReduceRight)
|
- [ReduceRight](#ReduceRight)
|
||||||
- [Replace](#Replace)
|
- [Replace](#Replace)
|
||||||
@@ -907,7 +909,7 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func FilterConcurrent[T any](slice []T, numOfThreads int, predicate func(index int, item T) bool) []T
|
func FilterConcurrent[T any](slice []T, predicate func(index int, item T) bool, numThreads int) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
@@ -925,7 +927,7 @@ func main() {
|
|||||||
return num%2 == 0
|
return num%2 == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
result := slice.FilterConcurrent(nums, 2, isEven)
|
result := slice.FilterConcurrent(nums, isEven, 2)
|
||||||
|
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
|
|
||||||
@@ -1177,6 +1179,42 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ForEachConcurrent">ForEachConcurrent</span>
|
||||||
|
|
||||||
|
<p>Applies the iteratee function to each item in the slice concurrently.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ForEachConcurrent[T any](slice []T, iteratee func(index int, item T), numThreads int)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run]()</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
|
|
||||||
|
result := make([]int, len(nums))
|
||||||
|
|
||||||
|
addOne := func(index int, value int) {
|
||||||
|
result[index] = value + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
slice.ForEachConcurrent(nums, addOne, 4)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [2 3 4 5 6 7 8 9]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="ForEachWithBreak">ForEachWithBreak</span>
|
### <span id="ForEachWithBreak">ForEachWithBreak</span>
|
||||||
|
|
||||||
<p>Iterates over elements of slice and invokes function for each element, when iteratee return false, will break the for each loop.</p>
|
<p>Iterates over elements of slice and invokes function for each element, when iteratee return false, will break the for each loop.</p>
|
||||||
@@ -1525,7 +1563,7 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
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, iteratee func(index int, item T) U, numThreads int) []U
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
@@ -1539,7 +1577,7 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
nums := []int{1, 2, 3, 4, 5, 6}
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
|
|
||||||
result := slice.MapConcurrent(nums, 4, func(_, n int) int { return n * n })
|
result := slice.MapConcurrent(nums, func(_, n int) int { return n * n }, 4)
|
||||||
|
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
|
|
||||||
@@ -1717,6 +1755,39 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <span id="ReduceConcurrent">ReduceConcurrent</span>
|
||||||
|
|
||||||
|
<p>Reduces the slice to a single value by applying the reducer function to each item in the slice concurrently.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReduceConcurrent[T any](slice []T, initial T, reducer func(index int, item T, agg T) T, numThreads int) T
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[运行]()</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||||
|
|
||||||
|
result := slice.ReduceConcurrent(nums, 0, func(_ int, item, agg int) int {
|
||||||
|
return agg + item
|
||||||
|
}, 1)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 55
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="ReduceBy">ReduceBy</span>
|
### <span id="ReduceBy">ReduceBy</span>
|
||||||
|
|
||||||
<p>Produces a value from slice by accumulating the result of each element as passed through the reducer function.</p>
|
<p>Produces a value from slice by accumulating the result of each element as passed through the reducer function.</p>
|
||||||
@@ -2437,7 +2508,7 @@ func main() {
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func UniqueByConcurrent[T comparable](slice []T, numOfThreads int, comparator func(item T, other T) bool) []T
|
func UniqueByConcurrent[T comparable](slice []T, comparator func(item T, other T) bool, numThreads int) []T
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
@@ -2450,10 +2521,9 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
|
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
|
||||||
numOfThreads := 4
|
|
||||||
comparator := func(item int, other int) bool { return item == other }
|
comparator := func(item int, other int) bool { return item == other }
|
||||||
|
|
||||||
result := slice.UniqueByConcurrent(nums, numOfThreads, comparator)
|
result := slice.UniqueByConcurrent(nums,comparator, 4)
|
||||||
|
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
// Output:
|
// Output:
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ func RandStringSlice(charset string, sliceLen, strLen int) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RandFromGivenSlice generate a random element from given slice.
|
// RandFromGivenSlice generate a random element from given slice.
|
||||||
|
// Play: todo
|
||||||
func RandFromGivenSlice[T any](slice []T) T {
|
func RandFromGivenSlice[T any](slice []T) T {
|
||||||
if len(slice) == 0 {
|
if len(slice) == 0 {
|
||||||
var zero T
|
var zero T
|
||||||
@@ -194,6 +195,35 @@ func RandFromGivenSlice[T any](slice []T) T {
|
|||||||
return slice[rand.Intn(len(slice))]
|
return slice[rand.Intn(len(slice))]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RandSliceFromGivenSlice generate a random slice of length num from given slice.
|
||||||
|
// - If repeatable is true, the generated slice may contain duplicate elements.
|
||||||
|
//
|
||||||
|
// Play: todo
|
||||||
|
func RandSliceFromGivenSlice[T any](slice []T, num int, repeatable bool) []T {
|
||||||
|
if num <= 0 || len(slice) == 0 {
|
||||||
|
return slice
|
||||||
|
}
|
||||||
|
|
||||||
|
if !repeatable && num > len(slice) {
|
||||||
|
num = len(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]T, num)
|
||||||
|
if repeatable {
|
||||||
|
for i := range result {
|
||||||
|
result[i] = slice[rand.Intn(len(slice))]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
shuffled := make([]T, len(slice))
|
||||||
|
copy(shuffled, slice)
|
||||||
|
rand.Shuffle(len(shuffled), func(i, j int) {
|
||||||
|
shuffled[i], shuffled[j] = shuffled[j], shuffled[i]
|
||||||
|
})
|
||||||
|
result = shuffled[:num]
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// RandUpper generate a random upper case string of specified length.
|
// RandUpper generate a random upper case string of specified length.
|
||||||
// Play: https://go.dev/play/p/29QfOh0DVuh
|
// Play: https://go.dev/play/p/29QfOh0DVuh
|
||||||
func RandUpper(length int) string {
|
func RandUpper(length int) string {
|
||||||
|
|||||||
@@ -47,18 +47,15 @@ func ExampleRandFromGivenSlice() {
|
|||||||
goods := []string{"apple", "banana", "cherry", "elderberry", "fig", "grape", "honeydew", "kiwi", "lemon",
|
goods := []string{"apple", "banana", "cherry", "elderberry", "fig", "grape", "honeydew", "kiwi", "lemon",
|
||||||
"mango", "nectarine", "orange"}
|
"mango", "nectarine", "orange"}
|
||||||
|
|
||||||
isInGoods := false
|
|
||||||
result := RandFromGivenSlice(goods)
|
result := RandFromGivenSlice(goods)
|
||||||
for _, good := range goods {
|
fmt.Println(result)
|
||||||
if good == result {
|
}
|
||||||
isInGoods = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Println(isInGoods)
|
|
||||||
|
|
||||||
// Output:
|
func ExampleRandSliceFromGivenSlice() {
|
||||||
// true
|
goods := []string{"apple", "banana", "cherry", "elderberry", "fig", "grape", "honeydew", "kiwi", "lemon",
|
||||||
|
"mango", "nectarine", "orange"}
|
||||||
|
chosen3goods := RandSliceFromGivenSlice(goods, 3, false)
|
||||||
|
fmt.Println(chosen3goods)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleRandUpper() {
|
func ExampleRandUpper() {
|
||||||
|
|||||||
@@ -292,6 +292,46 @@ func TestRandFromGivenSlice(t *testing.T) {
|
|||||||
assert.Equal(0, emtpyIntResult)
|
assert.Equal(0, emtpyIntResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRandSliceFromGivenSlice(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
assert := internal.NewAssert(t, "TestRandSliceFromGivenSlice")
|
||||||
|
|
||||||
|
randomSet := []any{"a", 8, "王", true, 1.1}
|
||||||
|
repeatableResult := RandSliceFromGivenSlice(randomSet, 8, true)
|
||||||
|
assert.Equal(8, len(repeatableResult))
|
||||||
|
unrepeatableResult := RandSliceFromGivenSlice(randomSet, 8, false)
|
||||||
|
assert.Equal(len(randomSet), len(unrepeatableResult))
|
||||||
|
|
||||||
|
var findCount int
|
||||||
|
for _, v := range repeatableResult {
|
||||||
|
for _, vv := range randomSet {
|
||||||
|
if v == vv {
|
||||||
|
findCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert.Equal(8, findCount)
|
||||||
|
findCount = 0
|
||||||
|
|
||||||
|
for _, v := range unrepeatableResult {
|
||||||
|
for _, vv := range randomSet {
|
||||||
|
if v == vv {
|
||||||
|
findCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert.Equal(len(randomSet), findCount)
|
||||||
|
|
||||||
|
emptyAnyRandomSet := []any{}
|
||||||
|
emptyAnyResult := RandSliceFromGivenSlice(emptyAnyRandomSet, 3, true)
|
||||||
|
assert.Equal([]any{}, emptyAnyResult)
|
||||||
|
|
||||||
|
emptyIntRandomSet := []int{}
|
||||||
|
emtpyIntResult := RandSliceFromGivenSlice(emptyIntRandomSet, 3, true)
|
||||||
|
assert.Equal([]int{}, emtpyIntResult)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestRandBool(t *testing.T) {
|
func TestRandBool(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
assert := internal.NewAssert(t, "TestRandBool")
|
assert := internal.NewAssert(t, "TestRandBool")
|
||||||
|
|||||||
+101
-16
@@ -8,13 +8,54 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ForEachConcurrent applies the iteratee function to each item in the slice concurrently.
|
||||||
|
// Play: todo
|
||||||
|
func ForEachConcurrent[T any](slice []T, iteratee func(index int, item T), numThreads int) {
|
||||||
|
sliceLen := len(slice)
|
||||||
|
if sliceLen == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if numThreads <= 0 {
|
||||||
|
numThreads = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
chunkSize := (sliceLen + numThreads - 1) / numThreads
|
||||||
|
|
||||||
|
for i := 0; i < numThreads; i++ {
|
||||||
|
start := i * chunkSize
|
||||||
|
end := start + chunkSize
|
||||||
|
|
||||||
|
if start >= sliceLen {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if end > sliceLen {
|
||||||
|
end = sliceLen
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func(start, end int) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
for j := start; j < end; j++ {
|
||||||
|
iteratee(j, slice[j])
|
||||||
|
}
|
||||||
|
}(start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
// MapConcurrent applies the iteratee function to each item in the slice concurrently.
|
// 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, iteratee func(index int, item T) U, numThreads int) []U {
|
||||||
result := make([]U, len(slice))
|
result := make([]U, len(slice))
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
workerChan := make(chan struct{}, numOfThreads)
|
workerChan := make(chan struct{}, numThreads)
|
||||||
|
|
||||||
for index, item := range slice {
|
for index, item := range slice {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
@@ -35,13 +76,57 @@ func MapConcurrent[T any, U any](slice []T, numOfThreads int, iteratee func(inde
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReduceConcurrent reduces the slice to a single value by applying the reducer function to each item in the slice concurrently.
|
||||||
|
// Play: todo
|
||||||
|
func ReduceConcurrent[T any](slice []T, initial T, reducer func(index int, item T, agg T) T, numThreads int) T {
|
||||||
|
if numThreads <= 0 {
|
||||||
|
numThreads = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
var mu sync.Mutex
|
||||||
|
|
||||||
|
sliceLen := len(slice)
|
||||||
|
chunkSize := (sliceLen + numThreads - 1) / numThreads
|
||||||
|
results := make([]T, numThreads)
|
||||||
|
|
||||||
|
for i := 0; i < numThreads; i++ {
|
||||||
|
start := i * chunkSize
|
||||||
|
end := start + chunkSize
|
||||||
|
if end > sliceLen {
|
||||||
|
end = sliceLen
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func(i, start, end int) {
|
||||||
|
defer wg.Done()
|
||||||
|
tempResult := initial
|
||||||
|
for j := start; j < end; j++ {
|
||||||
|
tempResult = reducer(j, slice[j], tempResult)
|
||||||
|
}
|
||||||
|
mu.Lock()
|
||||||
|
results[i] = tempResult
|
||||||
|
mu.Unlock()
|
||||||
|
}(i, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
result := initial
|
||||||
|
for i, r := range results {
|
||||||
|
result = reducer(i, result, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// FilterConcurrent applies the provided filter function `predicate` to each element of the input slice concurrently.
|
// FilterConcurrent applies the provided filter function `predicate` to each element of the input slice concurrently.
|
||||||
// Play: todo
|
// Play: todo
|
||||||
func FilterConcurrent[T any](slice []T, numOfThreads int, predicate func(index int, item T) bool) []T {
|
func FilterConcurrent[T any](slice []T, predicate func(index int, item T) bool, numThreads int) []T {
|
||||||
result := make([]T, 0)
|
result := make([]T, 0)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
workerChan := make(chan struct{}, numOfThreads)
|
workerChan := make(chan struct{}, numThreads)
|
||||||
|
|
||||||
for index, item := range slice {
|
for index, item := range slice {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
@@ -66,20 +151,20 @@ func FilterConcurrent[T any](slice []T, numOfThreads int, predicate func(index i
|
|||||||
|
|
||||||
// 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 numThreads parameter specifies the number of threads to use
|
||||||
// If numOfThreads is less than or equal to 0, it will be set to 1
|
// If numThreads is less than or equal to 0, it will be set to 1
|
||||||
// The comparator function should return true if the two elements are equal
|
// The comparator function should return true if the two elements are equal
|
||||||
// Play: todo
|
// Play: todo
|
||||||
func UniqueByConcurrent[T comparable](slice []T, numOfThreads int, comparator func(item T, other T) bool) []T {
|
func UniqueByConcurrent[T comparable](slice []T, comparator func(item T, other T) bool, numThreads int) []T {
|
||||||
if numOfThreads <= 0 {
|
if numThreads <= 0 {
|
||||||
numOfThreads = 1
|
numThreads = 1
|
||||||
} else if numOfThreads > len(slice) {
|
} else if numThreads > len(slice) {
|
||||||
numOfThreads = len(slice)
|
numThreads = len(slice)
|
||||||
}
|
}
|
||||||
|
|
||||||
maxThreads := runtime.NumCPU()
|
maxThreads := runtime.NumCPU()
|
||||||
if numOfThreads > maxThreads {
|
if numThreads > maxThreads {
|
||||||
numOfThreads = maxThreads
|
numThreads = maxThreads
|
||||||
}
|
}
|
||||||
|
|
||||||
removeDuplicate := func(items []T, comparator func(item T, other T) bool) []T {
|
removeDuplicate := func(items []T, comparator func(item T, other T) bool) []T {
|
||||||
@@ -99,9 +184,9 @@ func UniqueByConcurrent[T comparable](slice []T, numOfThreads int, comparator fu
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
chunkSize := (len(slice) + numOfThreads - 1) / numOfThreads
|
chunkSize := (len(slice) + numThreads - 1) / numThreads
|
||||||
|
|
||||||
chunks := make([][]T, 0, numOfThreads)
|
chunks := make([][]T, 0, numThreads)
|
||||||
for i := 0; i < len(slice); i += chunkSize {
|
for i := 0; i < len(slice); i += chunkSize {
|
||||||
end := i + chunkSize
|
end := i + chunkSize
|
||||||
if end > len(slice) {
|
if end > len(slice) {
|
||||||
@@ -114,7 +199,7 @@ func UniqueByConcurrent[T comparable](slice []T, numOfThreads int, comparator fu
|
|||||||
index int
|
index int
|
||||||
data []T
|
data []T
|
||||||
}
|
}
|
||||||
resultCh := make(chan resultChunk, numOfThreads)
|
resultCh := make(chan resultChunk, numThreads)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
for i, chunk := range chunks {
|
for i, chunk := range chunks {
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ func ExampleFilterConcurrent() {
|
|||||||
return num%2 == 0
|
return num%2 == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
result := FilterConcurrent(nums, 2, isEven)
|
result := FilterConcurrent(nums, isEven, 2)
|
||||||
|
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
|
|
||||||
@@ -429,6 +429,23 @@ func ExampleForEach() {
|
|||||||
// [2 3 4]
|
// [2 3 4]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleForEachConcurrent() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
|
|
||||||
|
result := make([]int, len(nums))
|
||||||
|
|
||||||
|
addOne := func(index int, value int) {
|
||||||
|
result[index] = value + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ForEachConcurrent(nums, addOne, 4)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [2 3 4 5 6 7 8 9]
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleForEachWithBreak() {
|
func ExampleForEachWithBreak() {
|
||||||
numbers := []int{1, 2, 3, 4, 5}
|
numbers := []int{1, 2, 3, 4, 5}
|
||||||
|
|
||||||
@@ -510,6 +527,18 @@ func ExampleReduce() {
|
|||||||
// 6
|
// 6
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleReduceConcurrent() {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||||
|
result := ReduceConcurrent(nums, 0, func(_ int, item, agg int) int {
|
||||||
|
return agg + item
|
||||||
|
}, 1)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 55
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleReduceBy() {
|
func ExampleReduceBy() {
|
||||||
result1 := ReduceBy([]int{1, 2, 3, 4}, 0, func(_ int, item int, agg int) int {
|
result1 := ReduceBy([]int{1, 2, 3, 4}, 0, func(_ int, item int, agg int) int {
|
||||||
return agg + item
|
return agg + item
|
||||||
@@ -1203,10 +1232,9 @@ func ExampleLeftPadding() {
|
|||||||
|
|
||||||
func ExampleUniqueByConcurrent() {
|
func ExampleUniqueByConcurrent() {
|
||||||
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
|
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
|
||||||
numOfThreads := 4
|
|
||||||
comparator := func(item int, other int) bool { return item == other }
|
comparator := func(item int, other int) bool { return item == other }
|
||||||
|
|
||||||
result := UniqueByConcurrent(nums, numOfThreads, comparator)
|
result := UniqueByConcurrent(nums, comparator, 4)
|
||||||
|
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
|
|
||||||
@@ -1216,7 +1244,7 @@ func ExampleUniqueByConcurrent() {
|
|||||||
|
|
||||||
func ExampleMapConcurrent() {
|
func ExampleMapConcurrent() {
|
||||||
nums := []int{1, 2, 3, 4, 5, 6}
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
result := MapConcurrent(nums, 4, func(_, n int) int { return n * n })
|
result := MapConcurrent(nums, func(_, n int) int { return n * n }, 4)
|
||||||
|
|
||||||
fmt.Println(result)
|
fmt.Println(result)
|
||||||
|
|
||||||
|
|||||||
+112
-8
@@ -410,6 +410,73 @@ func TestForEach(t *testing.T) {
|
|||||||
assert.Equal([]int{3, 4, 5, 6, 7}, result)
|
assert.Equal([]int{3, 4, 5, 6, 7}, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestForEachConcurrent(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestForEachConcurrent")
|
||||||
|
|
||||||
|
t.Run("single thread", func(t *testing.T) {
|
||||||
|
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||||
|
result := make([]int, len(numbers))
|
||||||
|
|
||||||
|
addOne := func(index int, value int) {
|
||||||
|
result[index] = value + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ForEachConcurrent(numbers, addOne, 1)
|
||||||
|
|
||||||
|
expected := []int{2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||||
|
assert.Equal(expected, result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("normal", func(t *testing.T) {
|
||||||
|
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||||
|
result := make([]int, len(numbers))
|
||||||
|
|
||||||
|
addOne := func(index int, value int) {
|
||||||
|
result[index] = value + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ForEachConcurrent(numbers, addOne, 4)
|
||||||
|
|
||||||
|
expected := []int{2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||||
|
assert.Equal(expected, result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("negative threads", func(t *testing.T) {
|
||||||
|
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||||
|
result := make([]int, len(numbers))
|
||||||
|
|
||||||
|
addOne := func(index int, value int) {
|
||||||
|
result[index] = value + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ForEachConcurrent(numbers, addOne, -4)
|
||||||
|
|
||||||
|
expected := []int{2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||||
|
assert.Equal(expected, result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("high number threads", func(t *testing.T) {
|
||||||
|
numbers := make([]int, 1000)
|
||||||
|
for i := range numbers {
|
||||||
|
numbers[i] = i
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]int, len(numbers))
|
||||||
|
|
||||||
|
addOne := func(index int, value int) {
|
||||||
|
result[index] = value + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ForEachConcurrent(numbers, addOne, 50)
|
||||||
|
|
||||||
|
for i, item := range numbers {
|
||||||
|
assert.Equal(item+1, result[i])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestForEachWithBreak(t *testing.T) {
|
func TestForEachWithBreak(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -520,6 +587,44 @@ func TestReduce(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReduceConcurrent(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestReduceConcurrent")
|
||||||
|
|
||||||
|
t.Run("basic", func(t *testing.T) {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||||
|
result := ReduceConcurrent(nums, 0, func(_ int, item, agg int) int {
|
||||||
|
return agg + item
|
||||||
|
}, 4)
|
||||||
|
assert.Equal(55, result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("empty slice", func(t *testing.T) {
|
||||||
|
nums := []int{}
|
||||||
|
result := ReduceConcurrent(nums, 0, func(_ int, item, agg int) int {
|
||||||
|
return agg + item
|
||||||
|
}, 4)
|
||||||
|
assert.Equal(0, result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("single thread", func(t *testing.T) {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||||
|
result := ReduceConcurrent(nums, 0, func(_ int, item, agg int) int {
|
||||||
|
return agg + item
|
||||||
|
}, 1)
|
||||||
|
assert.Equal(55, result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("negative threads", func(t *testing.T) {
|
||||||
|
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||||
|
result := ReduceConcurrent(nums, 0, func(_ int, item, agg int) int {
|
||||||
|
return agg + item
|
||||||
|
}, -1)
|
||||||
|
assert.Equal(55, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestReduceBy(t *testing.T) {
|
func TestReduceBy(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -1509,10 +1614,9 @@ func TestUniqueByConcurrent(t *testing.T) {
|
|||||||
assert := internal.NewAssert(t, "TestUniqueByConcurrent")
|
assert := internal.NewAssert(t, "TestUniqueByConcurrent")
|
||||||
|
|
||||||
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
|
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
|
||||||
numOfThreads := 4
|
|
||||||
comparator := func(item int, other int) bool { return item == other }
|
comparator := func(item int, other int) bool { return item == other }
|
||||||
|
|
||||||
result := UniqueByConcurrent(nums, numOfThreads, comparator)
|
result := UniqueByConcurrent(nums, comparator, 4)
|
||||||
|
|
||||||
assert.Equal([]int{1, 2, 3, 4, 5, 6, 7}, result)
|
assert.Equal([]int{1, 2, 3, 4, 5, 6, 7}, result)
|
||||||
}
|
}
|
||||||
@@ -1523,21 +1627,21 @@ func TestMapConcurrent(t *testing.T) {
|
|||||||
assert := internal.NewAssert(t, "TestMapConcurrent")
|
assert := internal.NewAssert(t, "TestMapConcurrent")
|
||||||
|
|
||||||
t.Run("empty slice", func(t *testing.T) {
|
t.Run("empty slice", func(t *testing.T) {
|
||||||
actual := MapConcurrent([]int{}, 4, func(_, n int) int { return n * n })
|
actual := MapConcurrent([]int{}, func(_, n int) int { return n * n }, 4)
|
||||||
assert.Equal([]int{}, actual)
|
assert.Equal([]int{}, actual)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("single thread", func(t *testing.T) {
|
t.Run("single thread", func(t *testing.T) {
|
||||||
nums := []int{1, 2, 3, 4, 5, 6}
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
expected := []int{1, 4, 9, 16, 25, 36}
|
expected := []int{1, 4, 9, 16, 25, 36}
|
||||||
actual := MapConcurrent(nums, 1, func(_, n int) int { return n * n })
|
actual := MapConcurrent(nums, func(_, n int) int { return n * n }, 1)
|
||||||
assert.Equal(expected, actual)
|
assert.Equal(expected, actual)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("multiple threads", func(t *testing.T) {
|
t.Run("multiple threads", func(t *testing.T) {
|
||||||
nums := []int{1, 2, 3, 4, 5, 6}
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
expected := []int{1, 4, 9, 16, 25, 36}
|
expected := []int{1, 4, 9, 16, 25, 36}
|
||||||
actual := MapConcurrent(nums, 4, func(_, n int) int { return n * n })
|
actual := MapConcurrent(nums, func(_, n int) int { return n * n }, 4)
|
||||||
assert.Equal(expected, actual)
|
assert.Equal(expected, actual)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1549,21 +1653,21 @@ func TestFilterConcurrent(t *testing.T) {
|
|||||||
assert := internal.NewAssert(t, "TestFilterConcurrent")
|
assert := internal.NewAssert(t, "TestFilterConcurrent")
|
||||||
|
|
||||||
t.Run("empty slice", func(t *testing.T) {
|
t.Run("empty slice", func(t *testing.T) {
|
||||||
actual := FilterConcurrent([]int{}, 4, func(_, n int) bool { return n != 0 })
|
actual := FilterConcurrent([]int{}, func(_, n int) bool { return n != 0 }, 4)
|
||||||
assert.Equal([]int{}, actual)
|
assert.Equal([]int{}, actual)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("single thread", func(t *testing.T) {
|
t.Run("single thread", func(t *testing.T) {
|
||||||
nums := []int{1, 2, 3, 4, 5, 6}
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
expected := []int{4, 5, 6}
|
expected := []int{4, 5, 6}
|
||||||
actual := FilterConcurrent(nums, 1, func(_, n int) bool { return n > 3 })
|
actual := FilterConcurrent(nums, func(_, n int) bool { return n > 3 }, 1)
|
||||||
assert.Equal(expected, actual)
|
assert.Equal(expected, actual)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("multiple threads", func(t *testing.T) {
|
t.Run("multiple threads", func(t *testing.T) {
|
||||||
nums := []int{1, 2, 3, 4, 5, 6}
|
nums := []int{1, 2, 3, 4, 5, 6}
|
||||||
expected := []int{4, 5, 6}
|
expected := []int{4, 5, 6}
|
||||||
actual := FilterConcurrent(nums, 4, func(_, n int) bool { return n > 3 })
|
actual := FilterConcurrent(nums, func(_, n int) bool { return n > 3 }, 4)
|
||||||
assert.Equal(expected, actual)
|
assert.Equal(expected, actual)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user