diff --git a/channel.go b/channel.go index cc65cf4..9a10852 100644 --- a/channel.go +++ b/channel.go @@ -5,7 +5,7 @@ import ( "sync" "time" - "github.com/samber/lo/internal/rand" + "github.com/samber/lo/internal/xrand" ) // DispatchingStrategy is a function that distributes messages to channels. @@ -92,7 +92,7 @@ func DispatchingStrategyRoundRobin[T any](msg T, index uint64, channels []<-chan // Play: https://go.dev/play/p/GEyGn3TdGk4 func DispatchingStrategyRandom[T any](msg T, index uint64, channels []<-chan T) int { for { - i := rand.IntN(len(channels)) + i := xrand.IntN(len(channels)) if channelIsNotFull(channels[i]) { return i } @@ -115,7 +115,7 @@ func DispatchingStrategyWeightedRandom[T any](weights []int) DispatchingStrategy return func(msg T, index uint64, channels []<-chan T) int { for { - i := seq[rand.IntN(len(seq))] + i := seq[xrand.IntN(len(seq))] if channelIsNotFull(channels[i]) { return i } diff --git a/find.go b/find.go index 184ce9e..534b4d7 100644 --- a/find.go +++ b/find.go @@ -5,7 +5,7 @@ import ( "time" "github.com/samber/lo/internal/constraints" - "github.com/samber/lo/internal/rand" + "github.com/samber/lo/internal/xrand" ) // IndexOf returns the index at which the first occurrence of a value is found in a slice or -1 @@ -660,7 +660,7 @@ type randomIntGenerator func(n int) int // Sample returns a random item from collection. // Play: https://go.dev/play/p/vCcSJbh5s6l func Sample[T any](collection []T) T { - result := SampleBy(collection, rand.IntN) + result := SampleBy(collection, xrand.IntN) return result } @@ -677,7 +677,7 @@ func SampleBy[T any](collection []T, randomIntGenerator randomIntGenerator) T { // Samples returns N random unique items from collection. // Play: https://go.dev/play/p/vCcSJbh5s6l func Samples[T any, Slice ~[]T](collection Slice, count int) Slice { - results := SamplesBy(collection, count, rand.IntN) + results := SamplesBy(collection, count, xrand.IntN) return results } diff --git a/internal/constraints/README.md b/internal/constraints/README.md new file mode 100644 index 0000000..27a3b1c --- /dev/null +++ b/internal/constraints/README.md @@ -0,0 +1,4 @@ + +# Constraints + +This package is for Go 1.18 retrocompatiblity purpose. diff --git a/internal/rand/ordered_go118.go b/internal/xrand/ordered_go118.go similarity index 98% rename from internal/rand/ordered_go118.go rename to internal/xrand/ordered_go118.go index badc173..410a5f3 100644 --- a/internal/rand/ordered_go118.go +++ b/internal/xrand/ordered_go118.go @@ -1,6 +1,6 @@ //go:build !go1.22 -package rand +package xrand import "math/rand" diff --git a/internal/rand/ordered_go122.go b/internal/xrand/ordered_go122.go similarity index 97% rename from internal/rand/ordered_go122.go rename to internal/xrand/ordered_go122.go index 56754fc..6bca250 100644 --- a/internal/rand/ordered_go122.go +++ b/internal/xrand/ordered_go122.go @@ -1,6 +1,6 @@ //go:build go1.22 -package rand +package xrand import "math/rand/v2" diff --git a/it/find.go b/it/find.go index fb66b76..a759bc6 100644 --- a/it/find.go +++ b/it/find.go @@ -10,7 +10,7 @@ import ( "github.com/samber/lo" "github.com/samber/lo/internal/constraints" - "github.com/samber/lo/internal/rand" + "github.com/samber/lo/internal/xrand" ) // IndexOf returns the index at which the first occurrence of a value is found in a sequence or -1 @@ -453,7 +453,7 @@ func NthOrEmpty[T any, N constraints.Integer](collection iter.Seq[T], nth N) T { // Will iterate through the entire sequence and allocate a slice large enough to hold all elements. // Long input sequences can cause excessive memory usage. func Sample[T any](collection iter.Seq[T]) T { - return SampleBy(collection, rand.IntN) + return SampleBy(collection, xrand.IntN) } // SampleBy returns a random item from collection, using randomIntGenerator as the random index generator. @@ -468,7 +468,7 @@ func SampleBy[T any](collection iter.Seq[T], randomIntGenerator func(int) int) T // Will iterate through the entire sequence and allocate a slice large enough to hold all elements. // Long input sequences can cause excessive memory usage. func Samples[T any, I ~func(func(T) bool)](collection I, count int) I { - return SamplesBy(collection, count, rand.IntN) + return SamplesBy(collection, count, xrand.IntN) } // SamplesBy returns N random unique items from collection, using randomIntGenerator as the random index generator. diff --git a/it/find_test.go b/it/find_test.go index 44a4f7a..d6c8b58 100644 --- a/it/find_test.go +++ b/it/find_test.go @@ -4,11 +4,11 @@ package it import ( "iter" - "math/rand/v2" "slices" "testing" "time" + "github.com/samber/lo/internal/xrand" "github.com/stretchr/testify/assert" ) @@ -687,8 +687,8 @@ func TestSampleBy(t *testing.T) { t.Parallel() is := assert.New(t) - result1 := SampleBy(values("a", "b", "c"), rand.IntN) - result2 := SampleBy(values[string](), rand.IntN) + result1 := SampleBy(values("a", "b", "c"), xrand.IntN) + result2 := SampleBy(values[string](), xrand.IntN) is.True(Contains(values("a", "b", "c"), result1)) is.Empty(result2) @@ -714,14 +714,14 @@ func TestSamplesBy(t *testing.T) { t.Parallel() is := assert.New(t) - result1 := SamplesBy(values("a", "b", "c"), 3, rand.IntN) - result2 := SamplesBy(values[string](), 3, rand.IntN) + result1 := SamplesBy(values("a", "b", "c"), 3, xrand.IntN) + result2 := SamplesBy(values[string](), 3, xrand.IntN) is.ElementsMatch(slices.Collect(result1), []string{"a", "b", "c"}) is.Empty(slices.Collect(result2)) type myStrings iter.Seq[string] allStrings := myStrings(values("", "foo", "bar")) - nonempty := SamplesBy(allStrings, 2, rand.IntN) + nonempty := SamplesBy(allStrings, 2, xrand.IntN) is.IsType(nonempty, allStrings, "type preserved") } diff --git a/mutable/slice.go b/mutable/slice.go index 44683b2..f3412c1 100644 --- a/mutable/slice.go +++ b/mutable/slice.go @@ -1,6 +1,6 @@ package mutable -import "github.com/samber/lo/internal/rand" +import "github.com/samber/lo/internal/xrand" // Filter is a generic function that modifies the input slice in-place to contain only the elements // that satisfy the provided predicate function. The predicate function takes an element of the slice and its index, @@ -55,7 +55,7 @@ func MapI[T any, Slice ~[]T](collection Slice, fn func(item T, index int) T) { // Shuffle returns a slice of shuffled values. Uses the Fisher-Yates shuffle algorithm. // Play: https://go.dev/play/p/2xb3WdLjeSJ func Shuffle[T any, Slice ~[]T](collection Slice) { - rand.Shuffle(len(collection), func(i, j int) { + xrand.Shuffle(len(collection), func(i, j int) { collection[i], collection[j] = collection[j], collection[i] }) } diff --git a/string.go b/string.go index 19a3c45..9590114 100644 --- a/string.go +++ b/string.go @@ -7,7 +7,7 @@ import ( "unicode" "unicode/utf8" - "github.com/samber/lo/internal/rand" + "github.com/samber/lo/internal/xrand" "golang.org/x/text/cases" "golang.org/x/text/language" @@ -60,14 +60,14 @@ func RandomString(size int, charset []rune) string { // Determine the corresponding bitmask, // e.g., for 62 characters, the bitmask would be 111111. var letterIDMask int64 = 1<= 0; { + for i, cache, remain := size-1, xrand.Int64(), letterIDMax; i >= 0; { // Regenerate the random number if all available bits have been used if remain == 0 { - cache, remain = rand.Int64(), letterIDMax + cache, remain = xrand.Int64(), letterIDMax } // Select a character from the charset if idx := int(cache & letterIDMask); idx < len(charset) {