3

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.

StevePoling
  • 319
  • 1
  • 15

1 Answers1

3

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]
Ringil
  • 6,277
  • 2
  • 23
  • 37