Last active
November 7, 2023 11:39
-
-
Save cemolcay/83dc1e180d7e2a57302e1c384e39f4eb to your computer and use it in GitHub Desktop.
Weighted Random Picker Swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class WeightedRandom<T> { | |
var elements: [Element] | |
init(elements: [Element] = []) { | |
self.elements = elements | |
} | |
struct Element { | |
let item: T | |
let weight: Double | |
} | |
func randomElement() -> T? { | |
guard elements.count > 0 else { return nil } | |
// Create an array to store the cumulative sum of weights | |
var cumulativeWeights: [Double] = [] | |
var totalWeight: Double = 0.0 | |
// Calculate the cumulative sum of weights | |
for element in elements { | |
totalWeight += element.weight | |
cumulativeWeights.append(totalWeight) | |
} | |
// Generate a random number between 0 and the total weight | |
let randomValue = Double.random(in: 0..<totalWeight) | |
// Find the element that corresponds to the random value | |
var selectedElement: T? | |
for i in 0..<elements.count { | |
if randomValue <= cumulativeWeights[i] { | |
selectedElement = elements[i].item | |
break | |
} | |
} | |
return selectedElement | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage: