Skip to content

Commit

Permalink
feat: add RandSliceFromGivenSlice function (#236)
Browse files Browse the repository at this point in the history
  • Loading branch information
cannian1 authored Aug 15, 2024
1 parent 7b4e060 commit c2a5335
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 10 deletions.
28 changes: 28 additions & 0 deletions docs/api/packages/random.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
- [RandInt](#RandInt)
- [RandString](#RandString)
- [RandFromGivenSlice](#RandFromGivenSlice)
- [RandSliceFromGivenSlice](#RandSliceFromGivenSlice)
- [RandUpper](#RandUpper)
- [RandLower](#RandLower)
- [RandNumeral](#RandNumeral)
Expand Down Expand Up @@ -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>

<p>生成给定长度的随机大写字母字符串</p>
Expand Down
29 changes: 29 additions & 0 deletions docs/en/api/packages/random.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
- [RandBytes](#RandBytes)
- [RandInt](#RandInt)
- [RandString](#RandString)
- [RandFromGivenSlice](#RandFromGivenSlice)
- [RandSliceFromGivenSlice](#RandSliceFromGivenSlice)
- [RandUpper](#RandUpper)
- [RandLower](#RandLower)
- [RandNumeral](#RandNumeral)
Expand Down Expand Up @@ -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>

<p>Generate a random upper case string</p>
Expand Down
30 changes: 30 additions & 0 deletions random/random.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ func RandStringSlice(charset string, sliceLen, strLen int) []string {
}

// RandFromGivenSlice generate a random element from given slice.
// Play: todo
func RandFromGivenSlice[T any](slice []T) T {
if len(slice) == 0 {
var zero T
Expand All @@ -194,6 +195,35 @@ func RandFromGivenSlice[T any](slice []T) T {
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.
// Play: https://go.dev/play/p/29QfOh0DVuh
func RandUpper(length int) string {
Expand Down
17 changes: 7 additions & 10 deletions random/random_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,15 @@ 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)
fmt.Println(result)
}

// Output:
// true
func ExampleRandSliceFromGivenSlice() {
goods := []string{"apple", "banana", "cherry", "elderberry", "fig", "grape", "honeydew", "kiwi", "lemon",
"mango", "nectarine", "orange"}
chosen3goods := RandSliceFromGivenSlice(goods, 3, false)
fmt.Println(chosen3goods)
}

func ExampleRandUpper() {
Expand Down
40 changes: 40 additions & 0 deletions random/random_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,46 @@ func TestRandFromGivenSlice(t *testing.T) {
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) {
t.Parallel()
assert := internal.NewAssert(t, "TestRandBool")
Expand Down

0 comments on commit c2a5335

Please sign in to comment.