我有一个F#列表,我正在列出该列表中的两个元素 如果列表中包含10个元素:
let rnd = new Random()
let elem1 = list.Item(rnd.Next(0,9))
let elem2 = list.Item(rnd.Next(0,9))
有机会elem1和elem2相等。
我已经检查了一些解决方法,其中大多数使用do while工作,但我不想实现可能永远不会以F#结尾的函数。
有没有办法在随机函数中创建限制?
First random : 0 <= x <= 9
Second random : 0 <= y <= 9 <> x
答案 0 :(得分:3)
一个简单的解决方案:
let rnd = new Random()
let ndx1 = rnd.Next(9)
let ndx2 =
let x = rnd.Next(8)
if x < ndx1 then x else x + 1
let elem1, elem2 = list.[ndx1], list.[ndx2]
另一种方法,使用数学并调用随机函数一次:
let r = Random().Next(9 * 8)
let x = 1 + r + r / 9
let elem1, elem2 = list.[x / 9], list.[x % 9]
可以概括为:
let getTwoElements lst =
let c = List.length lst
let x, y = Math.DivRem(Random().Next(c * (c-1)) * (c+1) / c + 1, c)
lst.[x], lst.[y]
答案 1 :(得分:3)
更具声明性的方法,考虑到您对图像中的点的评论:
let rnd = System.Random()
/// this will build you a list of 10 pairs of indices where a <> b.
let indices =
Seq.initInfinite (fun _ -> rnd.Next(0,10), rnd.Next(0,10))
|> Seq.filter (fun (a,b) -> a <> b)
|> Seq.take 10
|> List.ofSeq
/// map indices into actual points.
let elems =
let points = list |> Array.ofList
List.map (fun (a, b) -> points.[a], points.[b]) indices
作为旁注,请勿在列表中使用随机访问。他们并没有为此做出,而且表现也很差。首先将它们转换为数组。
答案 2 :(得分:0)
有很多方法可以实现这一目标。一个简单的就是这样:
open System
open System.Linq
let rnd = new Random()
let elem1 = list.Item(rnd.Next(0,9))
let elem2 = list.Where(fun x->x <> elem1).ElementAt(rnd.Next(0,8))