Best way to generate random indices into an array?

232 views Asked by At

Good afternoon. I have a set of values from which I'd like to draw a random subset.

My first thought was this:

let getRandomIndices size count =
  if size >= count then
    let r = System.Random()
    r.GetValues(0,size) |> Seq.take count |> Seq.toList
  else
    [0..size-1]

However, r.GetValues(0,size) may generate the same value multiple times. How can I get distinct values? My first thought is to repeatedly store indexes into a set until the set holds the desired number of elements? But this seems too procedural/not-functional enough? Is there a better way?

Or should I start with [0..size-1] and remove random elements from it until it holds the desired number indices?

I'm not really looking for the most efficient approach, but the most functional one. I am struggling to better grok the functional mindset.

1

There are 1 answers

1
Ringil On BEST ANSWER

If you sort a list of all the indices randomly, you can just take the first count number of elements in the list.

let getRandomIndices size count =
  if size >= count then
    let r = System.Random()
    [0..size-1] |> List.sortBy (fun _ -> r.Next()) |> List.take count
  else
    [0..size-1]