fox/xrand/weight.go

43 lines
776 B
Go
Raw Normal View History

2025-05-25 20:02:15 +08:00
package xrand
import "errors"
var ErrWeightRandomBadParam = errors.New("WeightRandom: bad param")
type randomItem[T any] struct {
Weight uint
Data T
}
// WeightRandom 加权随机
func WeightRandom[W int | uint | int32 | uint32 | int64 | uint64, T any](m map[W]T) (result T, err error) {
sum := uint(0)
var items []randomItem[T]
for weight, data := range m {
sum += uint(weight)
items = append(items, randomItem[T]{
Weight: uint(weight),
Data: data,
})
}
if len(items) == 0 || sum == 0 {
err = ErrWeightRandomBadParam
return
}
if len(items) == 1 {
return items[0].Data, nil
}
2025-05-26 16:02:54 +08:00
r := IntN(int(sum))
2025-05-25 20:02:15 +08:00
for _, item := range items {
r -= int(item.Weight)
if r < 0 {
return item.Data, nil
}
}
err = ErrWeightRandomBadParam
return
}