从 Go Slice 中选取一个随机值

问题描述 投票:0回答:4

情况:

我有一个值切片,需要从中随机选择一个值。然后我想将它与固定字符串连接起来。这是我到目前为止的代码:

func main() {
//create the reasons slice and append reasons to it
reasons := make([]string, 0)
reasons = append(reasons,
    "Locked out",
    "Pipes broke",
    "Food poisoning",
    "Not feeling well")

message := fmt.Sprint("Gonna work from home...", pick a random reason )
}

问题:

是否有内置功能可以帮助我完成“选择随机原因”部分?

random go slice
4个回答
156
投票

使用 Intn

 包中的函数 
rand
 来选择随机索引。

import (
  "math/rand"
  "time"
)

// ...

rand.Seed(time.Now().Unix()) // initialize global pseudo random generator
message := fmt.Sprint("Gonna work from home...", reasons[rand.Intn(len(reasons))])

其他解决方案是使用

Rand
对象。

s := rand.NewSource(time.Now().Unix())
r := rand.New(s) // initialize local pseudorandom generator 
r.Intn(len(reasons))

27
投票

只需选择一个随机整数 mod 切片长度:

rand.Seed(time.Now().Unix())
reasons := []string{
    "Locked out",
    "Pipes broke",
    "Food poisoning",
    "Not feeling well",
}
n := rand.Int() % len(reasons)
fmt.Print("Gonna work from home...", reasons[n])

游乐场:http://play.golang.org/p/fEHElLJrEZ。 (注意关于

rand.Seed
的赞扬。)


0
投票

您可以使用

build-in
函数来实现此目的,例如切片的
rand
length
。 试试这个:

func main() {
//create the reasons slice and append reasons to it
reasons := make([]string, 0)
reasons = append(reasons,
    "Locked out",
    "Pipes broke",
    "Food poisoning",
    "Not feeling well")

message := fmt.Sprint("Gonna work from home...", reasons[rand.Int(len(reasons)-1)])
}

-2
投票

由于这仍然出现在 Google 的 Golang 随机字符串生成的最高结果中,我想分享我一直在使用的内容。

这是我正在使用的解决方案:

package main

import (
  "fmt"
  "strings"
  "time"
)

var (
  opts  = strings.Split("option1,option2,option3", ",")
  start = time.Now()
)

func main() {
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
}

func getRandomOpt() string {
  len := len(opts)
  n := uint32(0)
  if len > 0 {
    n = getRandomUint32() % uint32(len)
  }
  return opts[n]
}

func getRandomUint32() uint32 {
  x := time.Now().UnixNano()
  return uint32((x >> 32) ^ x)
}

结果:

option2 665ns
option1 41.406µs
option1 44.817µs
option3 47.329µs
option1 49.725µs
option3 52µs
option2 54.393µs
option2 56.798µs
option1 59.098µs

就来源而言,我从 fastrand 复制了 getRandomUint32():https://github.com/valyala/fastrand

以及上面提出的解决方案。性能并没有那么不同,但我想分享结果。

package main

import (
  "fmt"
  "math/rand"
  "strings"
  "time"
)

var (
  opts  = strings.Split("option1,option2,option3", ",")
  start = time.Now()
)

func main() {
  rand.Seed(start.Unix())
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
  fmt.Println(getRandomOpt(), time.Since(start))
}

func getRandomOpt() string {
  return opts[rand.Intn(len(opts))]
}

结果:

option3 11.865µs
option2 48.415µs
option3 52.809µs
option1 55.536µs
option3 58.191µs
option3 60.793µs
option1 63.391µs
option2 65.982µs
option2 68.601µs

这些结果仅在本地运行了几次,我抓取了看似中间结果的结果。在迭代等方面肯定还有更多工作要做,但我只是想分享我所拥有的。

© www.soinside.com 2019 - 2024. All rights reserved.