diff --git a/docs/api/packages/random.md b/docs/api/packages/random.md index 5ee9015..dc63793 100644 --- a/docs/api/packages/random.md +++ b/docs/api/packages/random.md @@ -35,6 +35,8 @@ import ( - [RandUniqueIntSlice](#RandUniqueIntSlice) - [RandFloat](#RandFloat) - [RandFloats](#RandFloats) +- [RandStringSlice](#RandStringSlice) +
@@ -379,4 +381,85 @@ func main() { floatNumbers := random.RandFloats(5, 1.0, 5.0, 2) fmt.Println(floatNumber) //[3.42 3.99 1.3 2.38 4.23] (random) } +``` + +### RandStringSlice + +

生成随机字符串slice. 字符串类型需要是以下几种或者它们的组合: random.Numeral, random.LowwerLetters, random.UpperLetters random.Letters, random.SymbolChars, random.AllChars。

+ +函数签名: + +```go +func RandStringSlice(charset string, sliceLen, strLen int) []string +``` + +实例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + strs := random.RandStringSlice(random.Letters, 4, 6) + fmt.Println(strs) + + // output random string slice like below: + //[CooSMq RUFjDz FAeMPf heRyGv] +} +``` + +### RandBool + +

生成随机bool值(true or false)。

+ +函数签名: + +```go +func RandBool() bool +``` + +实例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + result := random.RandBool() + fmt.Println(result) // true or false (random) +} +``` + +### RandBoolSlice + +

生成特定长度的随机bool slice。

+ +函数签名: + +```go +func RandBoolSlice(length int) []bool +``` + +实例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + result := random.RandBoolSlice(2) + fmt.Println(result) // [true false] (random) +} ``` \ No newline at end of file diff --git a/docs/en/api/packages/random.md b/docs/en/api/packages/random.md index f5eff81..f6cdbe5 100644 --- a/docs/en/api/packages/random.md +++ b/docs/en/api/packages/random.md @@ -35,6 +35,9 @@ import ( - [RandUniqueIntSlice](#RandUniqueIntSlice) - [RandFloat](#RandFloat) - [RandFloats](#RandFloats) +- [RandStringSlice](#RandStringSlice) +- [RandBool](#RandBool) +- [RandBoolSlice](#RandBoolSlice)
@@ -380,4 +383,86 @@ func main() { floatNumbers := random.RandFloats(5, 1.0, 5.0, 2) fmt.Println(floatNumbers) //[3.42 3.99 1.3 2.38 4.23] (random) } +``` + + +### RandStringSlice + +

Generate a slice of random string of length strLen based on charset. chartset should be one of the following: random.Numeral, random.LowwerLetters, random.UpperLetters random.Letters, random.SymbolChars, random.AllChars. or a combination of them.

+ +Signature: + +```go +func RandStringSlice(charset string, sliceLen, strLen int) []string +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + strs := random.RandStringSlice(random.Letters, 4, 6) + fmt.Println(strs) + + // output random string slice like below: + //[CooSMq RUFjDz FAeMPf heRyGv] +} +``` + +### RandBool + +

Generate a random boolean value (true or false).

+ +Signature: + +```go +func RandBool() bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + result := random.RandBool() + fmt.Println(result) // true or false (random) +} +``` + +### RandBoolSlice + +

Generates a random boolean slice of specified length.

+ +Signature: + +```go +func RandBoolSlice(length int) []bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + result := random.RandBoolSlice(2) + fmt.Println(result) // [true false] (random) +} ``` \ No newline at end of file diff --git a/random/random.go b/random/random.go index 0d692e8..a87bb17 100644 --- a/random/random.go +++ b/random/random.go @@ -23,6 +23,7 @@ const ( UpperLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" Letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" SymbolChars = "!@#$%^&*()_+-=[]{}|;':\",./<>?" + AllChars = Numeral + LowwerLetters + UpperLetters + SymbolChars ) var rn = rand.NewSource(time.Now().UnixNano()) @@ -31,6 +32,27 @@ func init() { rand.Seed(time.Now().UnixNano()) } +// RandBool generates a random boolean value (true or false). +// Play: todo +func RandBool() bool { + return rand.Intn(2) == 1 +} + +// RandBoolSlice generates a random boolean slice of specified length. +// Play: todo +func RandBoolSlice(length int) []bool { + if length <= 0 { + return []bool{} + } + + result := make([]bool, length) + for i := range result { + result[i] = RandBool() + } + + return result +} + // RandInt generate random int between [min, max). // Play: https://go.dev/play/p/pXyyAAI5YxD func RandInt(min, max int) int { @@ -49,6 +71,47 @@ func RandInt(min, max int) int { return rand.Intn(max-min) + min } +// RandIntSlice generates a slice of random integers. +// The generated integers are between min and max (exclusive). +// Play: todo +func RandIntSlice(length, min, max int) []int { + if length <= 0 || min > max { + return []int{} + } + + result := make([]int, length) + for i := range result { + result[i] = RandInt(min, max) + } + + return result +} + +// RandUniqueIntSlice generate a slice of random int of length that do not repeat. +// Play: https://go.dev/play/p/uBkRSOz73Ec +func RandUniqueIntSlice(length, min, max int) []int { + if min > max { + return []int{} + } + if length > max-min { + length = max - min + } + + nums := make([]int, length) + used := make(map[int]struct{}, length) + for i := 0; i < length; { + r := RandInt(min, max) + if _, use := used[r]; use { + continue + } + used[r] = struct{}{} + nums[i] = r + i++ + } + + return nums +} + // RandFloat generate random float64 number between [min, max) with specific precision. // Play: https://go.dev/play/p/zbD_tuobJtr func RandFloat(min, max float64, precision int) float64 { @@ -65,6 +128,24 @@ func RandFloat(min, max float64, precision int) float64 { return mathutil.RoundToFloat(n, precision) } +// RandFloats generate a slice of random float64 numbers of length that do not repeat. +// Play: https://go.dev/play/p/I3yndUQ-rhh +func RandFloats(length int, min, max float64, precision int) []float64 { + nums := make([]float64, length) + used := make(map[float64]struct{}, length) + for i := 0; i < length; { + r := RandFloat(min, max, precision) + if _, use := used[r]; use { + continue + } + used[r] = struct{}{} + nums[i] = r + i++ + } + + return nums +} + // RandBytes generate random byte slice. // Play: https://go.dev/play/p/EkiLESeXf8d func RandBytes(length int) []byte { @@ -80,12 +161,30 @@ func RandBytes(length int) []byte { return b } -// RandString generate random alpha string of specified length. +// RandString generate random alphabeta string of specified length. // Play: https://go.dev/play/p/W2xvRUXA7Mi func RandString(length int) string { return random(Letters, length) } +// RandString generate a slice of random string of length strLen based on charset. +// chartset should be one of the following: random.Numeral, random.LowwerLetters, random.UpperLetters +// random.Letters, random.SymbolChars, random.AllChars. or a combination of them. +// Play: todo +func RandStringSlice(charset string, sliceLen, strLen int) []string { + if sliceLen <= 0 || strLen <= 0 { + return []string{} + } + + result := make([]string, sliceLen) + + for i := range result { + result[i] = random(charset, strLen) + } + + return result +} + // RandUpper generate a random upper case string of specified length. // Play: https://go.dev/play/p/29QfOh0DVuh func RandUpper(length int) string { @@ -189,62 +288,3 @@ func UUIdV4() (string, error) { return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil } - -// RandIntSlice generates a slice of random integers. -// The generated integers are between min and max (exclusive). -// Play: todo -func RandIntSlice(length, min, max int) []int { - if length <= 0 || min > max { - return []int{} - } - - result := make([]int, length) - for i := range result { - result[i] = RandInt(min, max) - } - - return result -} - -// RandUniqueIntSlice generate a slice of random int of length that do not repeat. -// Play: https://go.dev/play/p/uBkRSOz73Ec -func RandUniqueIntSlice(length, min, max int) []int { - if min > max { - return []int{} - } - if length > max-min { - length = max - min - } - - nums := make([]int, length) - used := make(map[int]struct{}, length) - for i := 0; i < length; { - r := RandInt(min, max) - if _, use := used[r]; use { - continue - } - used[r] = struct{}{} - nums[i] = r - i++ - } - - return nums -} - -// RandFloats generate a slice of random float64 numbers of length that do not repeat. -// Play: https://go.dev/play/p/I3yndUQ-rhh -func RandFloats(length int, min, max float64, precision int) []float64 { - nums := make([]float64, length) - used := make(map[float64]struct{}, length) - for i := 0; i < length; { - r := RandFloat(min, max, precision) - if _, use := used[r]; use { - continue - } - used[r] = struct{}{} - nums[i] = r - i++ - } - - return nums -} diff --git a/random/random_test.go b/random/random_test.go index ea7e6ae..4da729e 100644 --- a/random/random_test.go +++ b/random/random_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/duke-git/lancet/v2/internal" + "github.com/duke-git/lancet/v2/validator" ) func TestRandString(t *testing.T) { @@ -220,3 +221,80 @@ func TestRandIntSlice(t *testing.T) { assert.Equal(5, len(numbers)) }) } + +func TestRandStringSlice(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestRandStringSlice") + + t.Run("empty slice", func(t *testing.T) { + strs := RandStringSlice(Letters, -1, -1) + assert.Equal([]string{}, strs) + + strs = RandStringSlice(Letters, 0, 0) + assert.Equal([]string{}, strs) + + strs = RandStringSlice(Letters, -1, 0) + assert.Equal([]string{}, strs) + + strs = RandStringSlice(Letters, 0, -1) + assert.Equal([]string{}, strs) + + strs = RandStringSlice(Letters, 1, 0) + assert.Equal([]string{}, strs) + + strs = RandStringSlice(Letters, 0, 1) + assert.Equal([]string{}, strs) + }) + + t.Run("random string slice", func(t *testing.T) { + strs := RandStringSlice(Letters, 4, 6) + assert.Equal(4, len(strs)) + + for _, s := range strs { + assert.Equal(true, validator.IsAlpha(s)) + assert.Equal(6, len(s)) + } + }) + + // fail test: chinese character is not supported for now + // t.Run("random string slice of chinese ", func(t *testing.T) { + // strs := RandStringSlice("你好你好你好你好你好你好你好你好你好", 4, 6) + // t.Log(strs) + + // assert.Equal(4, len(strs)) + // for _, s := range strs { + // assert.Equal(true, validator.ContainChinese(s)) + // assert.Equal(6, len(s)) + // } + // }) +} + +func TestRandBool(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestRandBool") + + result := RandBool() + assert.Equal(true, result == true || result == false) +} + +func TestRandBoolSlice(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestRandBoolSlice") + + t.Run("empty slice", func(t *testing.T) { + bools := RandBoolSlice(-1) + assert.Equal([]bool{}, bools) + + bools = RandBoolSlice(0) + assert.Equal([]bool{}, bools) + }) + + t.Run("random bool slice", func(t *testing.T) { + bools := RandBoolSlice(6) + assert.Equal(6, len(bools)) + + for _, b := range bools { + assert.Equal(true, b == true || b == false) + } + }) +}