43 lines
776 B
Go
43 lines
776 B
Go
![]() |
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
|
||
|
}
|
||
|
|
||
|
r := Intn(int(sum))
|
||
|
for _, item := range items {
|
||
|
r -= int(item.Weight)
|
||
|
if r < 0 {
|
||
|
return item.Data, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
err = ErrWeightRandomBadParam
|
||
|
return
|
||
|
}
|