mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-17 11:12:28 +08:00
Compare commits
5 Commits
5c580ed013
...
7b4e060f85
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b4e060f85 | ||
|
|
a360372aa9 | ||
|
|
7f78a6b11e | ||
|
|
5c53cb5867 | ||
|
|
f7e9d5dc47 |
@@ -1419,9 +1419,13 @@ import "github.com/duke-git/lancet/v2/slice"
|
||||
- **<big>UniqueBy</big>** : remove duplicate elements from the input slice based on the values returned by the iteratee function.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#UniqueBy)]
|
||||
[[play](https://go.dev/play/p/UR323iZLDpv)]
|
||||
- **<big>UniqueByComparator</big>** : remove duplicate elements from the input slice using the provided comparator function.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#UniqueByComparator)]
|
||||
- **<big>UniqueByField</big>** : remove duplicate elements in struct slice by struct field.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#UniqueByField)]
|
||||
[[play](https://go.dev/play/p/6cifcZSPIGu)]
|
||||
- **<big>UniqueByParallel</big>** : remove duplicate elements from the slice by parallel.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#UniqueByParallel)]
|
||||
- **<big>Union</big>** : creates a slice of unique elements, in order, from all given slices.
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Union)]
|
||||
[[play](https://go.dev/play/p/hfXV1iRIZOf)]
|
||||
|
||||
@@ -1420,9 +1420,13 @@ import "github.com/duke-git/lancet/v2/slice"
|
||||
- **<big>UniqueBy</big>** : 根据迭代函数返回的值,从输入切片中移除重复元素。此函数保持元素的顺序。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#UniqueBy)]
|
||||
[[play](https://go.dev/play/p/UR323iZLDpv)]
|
||||
- **<big>UniqueByComparator</big>** : 使用提供的比较器函数从输入切片中移除重复元素。此函数保持元素的顺序。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#UniqueByComparator)]
|
||||
- **<big>UniqueByField</big>** : 根据struct字段对struct切片去重复。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#UniqueByField)]
|
||||
[[play](https://go.dev/play/p/6cifcZSPIGu)]
|
||||
- **<big>UniqueByParallel</big>** : 并发的从输入切片中移除重复元素,结果保持元素的顺序。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#UniqueByParallel)]
|
||||
- **<big>Union</big>** : 合并多个切片。
|
||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Union)]
|
||||
[[play](https://go.dev/play/p/hfXV1iRIZOf)]
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
- [RandBytes](#RandBytes)
|
||||
- [RandInt](#RandInt)
|
||||
- [RandString](#RandString)
|
||||
- [RandFromGivenSlice](#RandFromGivenSlice)
|
||||
- [RandUpper](#RandUpper)
|
||||
- [RandLower](#RandLower)
|
||||
- [RandNumeral](#RandNumeral)
|
||||
@@ -122,6 +123,33 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="RandFromGivenSlice">RandFromGivenSlice</span>
|
||||
|
||||
<p>从给定切片中随机生成元素</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func RandFromGivenSlice[T any](slice []T) 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() {
|
||||
nicknames := []string{"张三", "李四", "王五", "赵六", "钱七"}
|
||||
randElm := random.RandFromGivenSlice(nicknames)
|
||||
fmt.Println(randElm)
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="RandUpper">RandUpper</span>
|
||||
|
||||
<p>生成给定长度的随机大写字母字符串</p>
|
||||
|
||||
@@ -6,7 +6,8 @@ slice 包包含操作切片的方法集合。
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/slice/slice_concurrent.go](https://github.com/duke-git/lancet/blob/main/slice/slice_concurrent.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -44,6 +45,7 @@ import (
|
||||
- [Equal](#Equal)
|
||||
- [EqualWith](#EqualWith)
|
||||
- [Filter](#Filter)
|
||||
- [FilterConcurrent](#FilterConcurrent)
|
||||
- [Find<sup>deprecated</sup>](#Find)
|
||||
- [FindBy](#FindBy)
|
||||
- [FindLast<sup>deprecated</sup>](#FindLast)
|
||||
@@ -61,6 +63,7 @@ import (
|
||||
- [IndexOf](#IndexOf)
|
||||
- [LastIndexOf](#LastIndexOf)
|
||||
- [Map](#Map)
|
||||
- [MapConcurrent](#MapConcurrent)
|
||||
- [FilterMap](#FilterMap)
|
||||
- [FlatMap](#FlatMap)
|
||||
- [Merge](#Merge)
|
||||
@@ -86,7 +89,9 @@ import (
|
||||
- [ToSlicePointer](#ToSlicePointer)
|
||||
- [Unique](#Unique)
|
||||
- [UniqueBy](#UniqueBy)
|
||||
- [UniqueByComparator](#UniqueByComparator)
|
||||
- [UniqueByField](#UniqueByField)
|
||||
- [UniqueByConcurrent](#UniqueByConcurrent)
|
||||
- [Union](#Union)
|
||||
- [UnionBy](#UnionBy)
|
||||
- [UpdateAt](#UpdateAt)
|
||||
@@ -897,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>
|
||||
|
||||
<p>遍历slice的元素,返回第一个通过predicate函数真值测试的元素</p>
|
||||
@@ -1449,7 +1488,7 @@ func main() {
|
||||
|
||||
### <span id="Map">Map</span>
|
||||
|
||||
<p>对slice中的每个元素执行map函数以创建一个新切片</p>
|
||||
<p>对slice中的每个元素执行map函数以创建一个新切片。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -1481,6 +1520,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>
|
||||
|
||||
<p>返回一个将filter和map操作应用于给定切片的切片。 iteratee回调函数应该返回两个值:1,结果值。2,结果值是否应该被包含在返回的切片中。</p>
|
||||
@@ -2327,6 +2396,73 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="UniqueByComparator">UniqueByComparator</span>
|
||||
|
||||
<p>使用提供的比较器函数从输入切片中移除重复元素。此函数保持元素的顺序。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func UniqueByComparator[T comparable](slice []T, comparator func(item T, other T) bool) []T
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/slice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
uniqueNums := slice.UniqueByComparator([]int{1, 2, 3, 1, 2, 4, 5, 6, 4}, func(item int, other int) bool {
|
||||
return item == other
|
||||
})
|
||||
|
||||
caseInsensitiveStrings := slice.UniqueByComparator([]string{"apple", "banana", "Apple", "cherry", "Banana", "date"}, func(item string, other string) bool {
|
||||
return strings.ToLower(item) == strings.ToLower(other)
|
||||
})
|
||||
|
||||
fmt.Println(uniqueNums)
|
||||
fmt.Println(caseInsensitiveStrings)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
// [apple banana cherry date]
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="UniqueByConcurrent">UniqueByConcurrent</span>
|
||||
|
||||
<p>并发的从输入切片中移除重复元素,结果保持元素的顺序。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func UniqueByConcurrent[T comparable](slice []T, numOfThreads int, comparator func(item T, other T) bool) []T
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/slice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
|
||||
numOfThreads := 4
|
||||
comparator := func(item int, other int) bool { return item == other }
|
||||
|
||||
result := slice.UniqueByConcurrent(nums, numOfThreads, comparator)
|
||||
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// [1 2 3 4 5 6 7]
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="UniqueByField">UniqueByField</span>
|
||||
|
||||
<p>根据struct字段对struct切片去重复。</p>
|
||||
|
||||
@@ -121,6 +121,33 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="RandFromGivenSlice">RandFromGivenSlice</span>
|
||||
|
||||
<p>Generate a random element from given slice.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func RandFromGivenSlice[T any](slice []T) 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() {
|
||||
randomSet := []any{"a", 8, "hello", true, 1.1}
|
||||
randElm := random.RandFromGivenSlice(randomSet)
|
||||
fmt.Println(randElm)
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="RandUpper">RandUpper</span>
|
||||
|
||||
<p>Generate a random upper case string</p>
|
||||
|
||||
@@ -6,7 +6,8 @@ Package slice implements some functions to manipulate slice.
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/slice/slice_concurrent.go](https://github.com/duke-git/lancet/blob/main/slice/slice_concurrent.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -44,6 +45,7 @@ import (
|
||||
- [EqualWith](#EqualWith)
|
||||
- [Every](#Every)
|
||||
- [Filter](#Filter)
|
||||
- [FilterConcurrent](#FilterConcurrent)
|
||||
- [Find<sup>deprecated</sup>](#Find)
|
||||
- [FindBy](#FindBy)
|
||||
- [FindLast<sup>deprecated</sup>](#FindLast)
|
||||
@@ -61,6 +63,7 @@ import (
|
||||
- [IndexOf](#IndexOf)
|
||||
- [LastIndexOf](#LastIndexOf)
|
||||
- [Map](#Map)
|
||||
- [MapConcurrent](#MapConcurrent)
|
||||
- [FilterMap](#FilterMap)
|
||||
- [FlatMap](#FlatMap)
|
||||
- [Merge](#Merge)
|
||||
@@ -86,7 +89,9 @@ import (
|
||||
- [ToSlicePointer](#ToSlicePointer)
|
||||
- [Unique](#Unique)
|
||||
- [UniqueBy](#UniqueBy)
|
||||
- [UniqueByComparator](#UniqueByComparator)
|
||||
- [UniqueByField](#UniqueByField)
|
||||
- [UniqueByConcurrent](#UniqueByConcurrent)
|
||||
- [Union](#Union)
|
||||
- [UnionBy](#UnionBy)
|
||||
- [UpdateAt](#UpdateAt)
|
||||
@@ -895,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>
|
||||
|
||||
<p>Iterates over elements of slice, returning the first one that passes a truth test on function.</p>
|
||||
@@ -1479,6 +1518,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>
|
||||
|
||||
<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>
|
||||
@@ -2325,6 +2394,73 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="UniqueByComparator">UniqueByComparator</span>
|
||||
|
||||
<p>Removes duplicate elements from the input slice using the provided comparator function. The function maintains the order of the elements.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func UniqueByComparator[T comparable](slice []T, comparator func(item T, other T) bool) []T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/slice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
uniqueNums := slice.UniqueByComparator([]int{1, 2, 3, 1, 2, 4, 5, 6, 4}, func(item int, other int) bool {
|
||||
return item == other
|
||||
})
|
||||
|
||||
caseInsensitiveStrings := slice.UniqueByComparator([]string{"apple", "banana", "Apple", "cherry", "Banana", "date"}, func(item string, other string) bool {
|
||||
return strings.ToLower(item) == strings.ToLower(other)
|
||||
})
|
||||
|
||||
fmt.Println(uniqueNums)
|
||||
fmt.Println(caseInsensitiveStrings)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 6]
|
||||
// [apple banana cherry date]
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="UniqueByConcurrent">UniqueByConcurrent</span>
|
||||
|
||||
<p>Removes duplicate elements from the slice by parallel.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func UniqueByConcurrent[T comparable](slice []T, numOfThreads int, comparator func(item T, other T) bool) []T
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/slice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
|
||||
numOfThreads := 4
|
||||
comparator := func(item int, other int) bool { return item == other }
|
||||
|
||||
result := slice.UniqueByConcurrent(nums, numOfThreads, comparator)
|
||||
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// [1 2 3 4 5 6 7]
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="UniqueByField">UniqueByField</span>
|
||||
|
||||
<p>Remove duplicate elements in struct slice by struct field.</p>
|
||||
@@ -2647,14 +2783,14 @@ import (
|
||||
|
||||
func main() {
|
||||
strs := []string{"a", "b", "a", "c", "d", "a"}
|
||||
modifiedStrs, count := slice.SetToDefaultIf(strs, func(s string) bool { return "a" == s })
|
||||
|
||||
modifiedStrs, count := slice.SetToDefaultIf(strs, func(s string) bool { return "a" == s })
|
||||
|
||||
fmt.Println(modifiedStrs)
|
||||
fmt.Println(count)
|
||||
|
||||
fmt.Println(count)
|
||||
|
||||
// Output:
|
||||
// [ b c d ]
|
||||
// 3
|
||||
// [ b c d ]
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
@@ -2710,11 +2846,11 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
nums := []int{1, 2, 3, 4, 5}
|
||||
padded := slice.RightPadding(nums, 0, 3)
|
||||
fmt.Println(padded)
|
||||
// Output:
|
||||
// [1 2 3 4 5 0 0 0]
|
||||
nums := []int{1, 2, 3, 4, 5}
|
||||
padded := slice.RightPadding(nums, 0, 3)
|
||||
fmt.Println(padded)
|
||||
// Output:
|
||||
// [1 2 3 4 5 0 0 0]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -2737,10 +2873,10 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
nums := []int{1, 2, 3, 4, 5}
|
||||
padded := slice.LeftPadding(nums, 0, 3)
|
||||
fmt.Println(padded)
|
||||
// Output:
|
||||
// [0 0 0 1 2 3 4 5]
|
||||
nums := []int{1, 2, 3, 4, 5}
|
||||
padded := slice.LeftPadding(nums, 0, 3)
|
||||
fmt.Println(padded)
|
||||
// Output:
|
||||
// [0 0 0 1 2 3 4 5]
|
||||
}
|
||||
```
|
||||
@@ -185,6 +185,15 @@ func RandStringSlice(charset string, sliceLen, strLen int) []string {
|
||||
return result
|
||||
}
|
||||
|
||||
// RandFromGivenSlice generate a random element from given slice.
|
||||
func RandFromGivenSlice[T any](slice []T) T {
|
||||
if len(slice) == 0 {
|
||||
var zero T
|
||||
return zero
|
||||
}
|
||||
return slice[rand.Intn(len(slice))]
|
||||
}
|
||||
|
||||
// RandUpper generate a random upper case string of specified length.
|
||||
// Play: https://go.dev/play/p/29QfOh0DVuh
|
||||
func RandUpper(length int) string {
|
||||
|
||||
@@ -43,6 +43,24 @@ func ExampleRandString() {
|
||||
// 6
|
||||
}
|
||||
|
||||
func ExampleRandFromGivenSlice() {
|
||||
goods := []string{"apple", "banana", "cherry", "elderberry", "fig", "grape", "honeydew", "kiwi", "lemon",
|
||||
"mango", "nectarine", "orange"}
|
||||
|
||||
isInGoods := false
|
||||
result := RandFromGivenSlice(goods)
|
||||
for _, good := range goods {
|
||||
if good == result {
|
||||
isInGoods = true
|
||||
break
|
||||
}
|
||||
}
|
||||
fmt.Println(isInGoods)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
}
|
||||
|
||||
func ExampleRandUpper() {
|
||||
pattern := `^[A-Z]+$`
|
||||
reg := regexp.MustCompile(pattern)
|
||||
|
||||
@@ -269,6 +269,29 @@ func TestRandStringSlice(t *testing.T) {
|
||||
// })
|
||||
}
|
||||
|
||||
func TestRandFromGivenSlice(t *testing.T) {
|
||||
t.Parallel()
|
||||
assert := internal.NewAssert(t, "TestRandFromGivenSlice")
|
||||
|
||||
randomSet := []any{"a", 8, "王", true, 1.1}
|
||||
result := RandFromGivenSlice(randomSet)
|
||||
find := false
|
||||
for _, v := range randomSet {
|
||||
if v == result {
|
||||
find = true
|
||||
}
|
||||
}
|
||||
assert.Equal(true, find)
|
||||
|
||||
emptyAnyRandomSet := []any{}
|
||||
emptyAnyResult := RandFromGivenSlice(emptyAnyRandomSet)
|
||||
assert.IsNil(emptyAnyResult)
|
||||
|
||||
emptyIntRandomSet := []int{}
|
||||
emtpyIntResult := RandFromGivenSlice(emptyIntRandomSet)
|
||||
assert.Equal(0, emtpyIntResult)
|
||||
}
|
||||
|
||||
func TestRandBool(t *testing.T) {
|
||||
t.Parallel()
|
||||
assert := internal.NewAssert(t, "TestRandBool")
|
||||
|
||||
@@ -8,13 +8,69 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// 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))
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
// If numOfThreads 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
|
||||
// Play: todo
|
||||
func UniqueByParallel[T comparable](slice []T, numOfThreads int, comparator func(item T, other T) bool) []T {
|
||||
func UniqueByConcurrent[T comparable](slice []T, numOfThreads int, comparator func(item T, other T) bool) []T {
|
||||
if numOfThreads <= 0 {
|
||||
numOfThreads = 1
|
||||
} else if numOfThreads > len(slice) {
|
||||
@@ -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}
|
||||
|
||||
@@ -1139,6 +1154,7 @@ func ExampleRandom() {
|
||||
if idx >= 0 && idx < len(nums) && Contain(nums, val) {
|
||||
fmt.Println("okk")
|
||||
}
|
||||
|
||||
// Output:
|
||||
// okk
|
||||
}
|
||||
@@ -1148,6 +1164,7 @@ func ExampleSetToDefaultIf() {
|
||||
modifiedStrs, count := SetToDefaultIf(strs, func(s string) bool { return "a" == s })
|
||||
fmt.Println(modifiedStrs)
|
||||
fmt.Println(count)
|
||||
|
||||
// Output:
|
||||
// [ b c d ]
|
||||
// 3
|
||||
@@ -1170,6 +1187,7 @@ func ExampleRightPadding() {
|
||||
nums := []int{1, 2, 3, 4, 5}
|
||||
padded := RightPadding(nums, 0, 3)
|
||||
fmt.Println(padded)
|
||||
|
||||
// Output:
|
||||
// [1 2 3 4 5 0 0 0]
|
||||
}
|
||||
@@ -1178,18 +1196,30 @@ func ExampleLeftPadding() {
|
||||
nums := []int{1, 2, 3, 4, 5}
|
||||
padded := LeftPadding(nums, 0, 3)
|
||||
fmt.Println(padded)
|
||||
|
||||
// Output:
|
||||
// [0 0 0 1 2 3 4 5]
|
||||
}
|
||||
|
||||
func ExampleUniqueByParallel() {
|
||||
func ExampleUniqueByConcurrent() {
|
||||
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
|
||||
numOfThreads := 4
|
||||
comparator := func(item int, other int) bool { return item == other }
|
||||
|
||||
result := UniqueByParallel(nums, numOfThreads, comparator)
|
||||
result := UniqueByConcurrent(nums, numOfThreads, comparator)
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
// Output:
|
||||
// [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]
|
||||
}
|
||||
|
||||
@@ -1503,16 +1503,68 @@ func TestRightPaddingAndLeftPadding(t *testing.T) {
|
||||
assert.Equal([]int{0, 0, 0, 1, 2, 3, 4, 5, 0, 0, 0}, padded)
|
||||
}
|
||||
|
||||
func TestUniqueByParallel(t *testing.T) {
|
||||
func TestUniqueByConcurrent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := internal.NewAssert(t, "TestUniqueByParallel")
|
||||
assert := internal.NewAssert(t, "TestUniqueByConcurrent")
|
||||
|
||||
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
|
||||
numOfThreads := 4
|
||||
comparator := func(item int, other int) bool { return item == other }
|
||||
|
||||
result := UniqueByParallel(nums, numOfThreads, comparator)
|
||||
result := UniqueByConcurrent(nums, numOfThreads, comparator)
|
||||
|
||||
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)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
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