vRp.CD2g_test/utils/collection/random.go

237 lines
6.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package collection
import (
"fmt"
"github.com/kercylan98/minotaur/utils/random"
)
// ChooseRandomSliceElementRepeatN 返回 slice 中的 n 个可重复随机元素
// - 当 slice 长度为 0 或 n 小于等于 0 时将会返回 nil
func ChooseRandomSliceElementRepeatN[S ~[]V, V any](slice S, n int) (result []V) {
if len(slice) == 0 || n <= 0 {
return
}
result = make([]V, n)
m := len(slice) - 1
for i := 0; i < n; i++ {
result[i] = slice[random.Int(0, m)]
}
return
}
// ChooseRandomIndexRepeatN 返回 slice 中的 n 个可重复随机元素的索引
// - 当 slice 长度为 0 或 n 小于等于 0 时将会返回 nil
func ChooseRandomIndexRepeatN[S ~[]V, V any](slice S, n int) (result []int) {
if len(slice) == 0 || n <= 0 {
return
}
result = make([]int, n)
m := len(slice) - 1
for i := 0; i < n; i++ {
result[i] = random.Int(0, m)
}
return
}
// ChooseRandomSliceElement 返回 slice 中随机一个元素,当 slice 长度为 0 时将会得到 V 的零值
func ChooseRandomSliceElement[S ~[]V, V any](slice S) (v V) {
if len(slice) == 0 {
return
}
return slice[random.Int(0, len(slice)-1)]
}
// ChooseRandomIndex 返回 slice 中随机一个元素的索引,当 slice 长度为 0 时将会得到 -1
func ChooseRandomIndex[S ~[]V, V any](slice S) (index int) {
if len(slice) == 0 {
return -1
}
return random.Int(0, len(slice)-1)
}
// ChooseRandomSliceElementN 返回 slice 中的 n 个不可重复的随机元素
// - 当 slice 长度为 0 或 n 大于 slice 长度或小于 0 时将会发生 panic
func ChooseRandomSliceElementN[S ~[]V, V any](slice S, n int) (result []V) {
if len(slice) == 0 || n <= 0 || n > len(slice) {
panic(fmt.Errorf("n is greater than the length of the slice or less than 0, n: %d, length: %d", n, len(slice)))
}
result = make([]V, 0, n)
valid := ConvertSliceToIndexOnlyMap(slice)
for i := range valid {
result = append(result, slice[i])
if len(result) == n {
break
}
}
return
}
// ChooseRandomIndexN 获取切片中的 n 个随机元素的索引
// - 如果 n 大于切片长度或小于 0 时将会发生 panic
func ChooseRandomIndexN[S ~[]V, V any](slice S, n int) (result []int) {
if len(slice) == 0 {
return
}
if n > len(slice) || n < 0 {
panic(fmt.Errorf("inputN is greater than the length of the input or less than 0, inputN: %d, length: %d", n, len(slice)))
}
result = make([]int, n)
for i := 0; i < n; i++ {
result[i] = random.Int(0, len(slice)-1)
}
return
}
// ChooseRandomMapKeyRepeatN 获取 map 中的 n 个随机 key允许重复
// - 如果 n 大于 map 长度或小于 0 时将会发生 panic
func ChooseRandomMapKeyRepeatN[M ~map[K]V, K comparable, V any](m M, n int) (result []K) {
if m == nil {
return
}
if n > len(m) || n < 0 {
panic(fmt.Errorf("inputN is greater than the length of the map or less than 0, inputN: %d, length: %d", n, len(m)))
}
result = make([]K, n)
for i := 0; i < n; i++ {
for k := range m {
result[i] = k
break
}
}
return
}
// ChooseRandomMapValueRepeatN 获取 map 中的 n 个随机 n允许重复
// - 如果 n 大于 map 长度或小于 0 时将会发生 panic
func ChooseRandomMapValueRepeatN[M ~map[K]V, K comparable, V any](m M, n int) (result []V) {
if m == nil {
return
}
if n > len(m) || n < 0 {
panic(fmt.Errorf("inputN is greater than the length of the map or less than 0, inputN: %d, length: %d", n, len(m)))
}
result = make([]V, n)
for i := 0; i < n; i++ {
for _, v := range m {
result[i] = v
break
}
}
return
}
// ChooseRandomMapKeyAndValueRepeatN 获取 map 中的 n 个随机 key 和 v允许重复
// - 如果 n 大于 map 长度或小于 0 时将会发生 panic
func ChooseRandomMapKeyAndValueRepeatN[M ~map[K]V, K comparable, V any](m M, n int) M {
if m == nil {
return nil
}
if n > len(m) || n < 0 {
panic(fmt.Errorf("inputN is greater than the length of the map or less than 0, inputN: %d, length: %d", n, len(m)))
}
result := make(M, n)
for i := 0; i < n; i++ {
for k, v := range m {
result[k] = v
break
}
}
return result
}
// ChooseRandomMapKey 获取 map 中的随机 key
func ChooseRandomMapKey[M ~map[K]V, K comparable, V any](m M) (k K) {
if m == nil {
return
}
for k = range m {
return
}
return
}
// ChooseRandomMapValue 获取 map 中的随机 value
func ChooseRandomMapValue[M ~map[K]V, K comparable, V any](m M) (v V) {
if m == nil {
return
}
for _, v = range m {
return
}
return
}
// ChooseRandomMapKeyN 获取 map 中的 inputN 个随机 key
// - 如果 inputN 大于 map 长度或小于 0 时将会发生 panic
func ChooseRandomMapKeyN[M ~map[K]V, K comparable, V any](m M, n int) (result []K) {
if m == nil {
return
}
if n > len(m) || n < 0 {
panic(fmt.Errorf("inputN is greater than the length of the map or less than 0, inputN: %d, length: %d", n, len(m)))
}
result = make([]K, n)
i := 0
for k := range m {
result[i] = k
i++
if i == n {
break
}
}
return
}
// ChooseRandomMapValueN 获取 map 中的 n 个随机 value
// - 如果 n 大于 map 长度或小于 0 时将会发生 panic
func ChooseRandomMapValueN[M ~map[K]V, K comparable, V any](m M, n int) (result []V) {
if m == nil {
return
}
if n > len(m) || n < 0 {
panic(fmt.Errorf("inputN is greater than the length of the map or less than 0, inputN: %d, length: %d", n, len(m)))
}
result = make([]V, n)
i := 0
for _, v := range m {
result[i] = v
i++
if i == n {
break
}
}
return
}
// ChooseRandomMapKeyAndValue 获取 map 中的随机 key 和 v
func ChooseRandomMapKeyAndValue[M ~map[K]V, K comparable, V any](m M) (k K, v V) {
if m == nil {
return
}
for k, v = range m {
return
}
return
}
// ChooseRandomMapKeyAndValueN 获取 map 中的 inputN 个随机 key 和 v
// - 如果 n 大于 map 长度或小于 0 时将会发生 panic
func ChooseRandomMapKeyAndValueN[M ~map[K]V, K comparable, V any](m M, n int) M {
if m == nil {
return nil
}
if n > len(m) || n < 0 {
panic(fmt.Errorf("inputN is greater than the length of the map or less than 0, inputN: %d, length: %d", n, len(m)))
}
result := make(M, n)
i := 0
for k, v := range m {
result[k] = v
i++
if i == n {
break
}
}
return result
}