Skip to content

Instantly share code, notes, and snippets.

@asalom
Last active November 28, 2018 10:38
Show Gist options
  • Save asalom/6901b0b07f326535f2fd1a718aa1d996 to your computer and use it in GitHub Desktop.
Save asalom/6901b0b07f326535f2fd1a718aa1d996 to your computer and use it in GitHub Desktop.
public class ABTester {
public init() {}
/** Randomly chooses a weighted generic item from a list of item
- item: a weighted item
- more: more weighted items as a variadic parameter
- randomNumberGenerator: random number generator
- returns: the selected generic item
- discussion:
We force the first item to be provided so we ensure that we don't end up with an empty list of items
*/
public func ABTest<T>(item: (item: Void -> T, weight: Int), _ more: (item: Void -> T, weight: Int) ..., randomNumberGenerator: RandomValueGenerator) -> T {
return [[item], more].flatMap { $0 }.sorted {
randomNumberGenerator.generateRandomValueBetween(1, maxValue: $0.weight) >
randomNumberGenerator.generateRandomValueBetween(1, maxValue: $1.weight)
}.first!.item() // force unwrapping is 100% secure since we will always have at least one item
}
}
/// This protocol is to be implemented by those classes that generate a random number
public protocol RandomValueGenerator {
/**
Returns a random value between the specified parameters
- parameter minValue: The min value the random can be
- parameter maxValue: The max value the random can be
*/
func generateRandomValueBetween(minValue: Int, maxValue: Int) -> Int
}
public class RandomNumberGeneratorImpl: RandomValueGenerator {
public init() {}
public func generateRandomValueBetween(minValue: Int, maxValue: Int) -> Int {
return minValue + Int(arc4random_uniform(UInt32(maxValue - minValue + 1)))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment