Skip to content

An Implementation of random.shuffle in golang

使用golang实现类似Pythonrandom.shuffle的功能

The naive approach

func Shuffle(vals []int) []int {
  r := rand.New(rand.NewSource(time.Now().Unix()))
  ret := make([]int, len(vals))
  n := len(vals)
  for i := 0; i < n; i++ {
    randIndex := r.Intn(len(vals))
    ret[i] = vals[randIndex]
    vals = append(vals[:randIndex], vals[randIndex+1:]...)
  }
  return ret
}

or use rand.Perm() to do this a bit more efficiently

func Shuffle(vals []int) []int {
  r := rand.New(rand.NewSource(time.Now().Unix()))
  ret := make([]int, len(vals))
  perm := r.Perm(len(vals))
  for i, randIndex := range perm {
    ret[i] = vals[randIndex]
  }
  return ret
}

Shuffling without creating a new slice or array

func Shuffle(vals []int) {
  r := rand.New(rand.NewSource(time.Now().Unix()))
  for len(vals) > 0 {
    n := len(vals)
    randIndex := r.Intn(n)
    vals[n-1], vals[randIndex] = vals[randIndex], vals[n-1]
    vals = vals[:n-1]
  }
}

Using Generics to support different type of slice

// for go 1.18+
func Shuffle [Tx any] (vals []Tx) []Tx {
    r := rand.New(rand.NewSource(time.Now().Unix()))
    ret := make([]Tx, len(vals))
    perm := r.Perm(len(vals))
    for i, randIndex := range perm {
        ret[i] = vals[randIndex]
    }
    return ret
}

reference