Хм, вот один с Seq.scan, но он также кажется очень уродливым ...
type WeightedItem(id: int, weight: int) =
member self.id = id
member self.weight = weight
let selectItem (items: WeightedItem list) (rand:System.Random) =
let totalWeight = List.sumBy (fun (item: WeightedItem) -> item.weight) items
let selection = rand.Next(totalWeight) + 1
Seq.scan
(fun (runningWeight,found,itemO) (item: WeightedItem) ->
if not found then
let newRunningWeight = runningWeight + item.weight
newRunningWeight, newRunningWeight >= selection, Some(item)
else
(runningWeight,found,itemO))
(0,false,None)
items
|> Seq.find (fun (rw,f,i) -> f)
|> (fun (rw,f,i) -> i.Value)
let items = [new WeightedItem(1,100)
new WeightedItem(2,50)
new WeightedItem(3,25)]
let selection = selectItem items (new System.Random())