Last active
November 28, 2018 10:38
-
-
Save asalom/6901b0b07f326535f2fd1a718aa1d996 to your computer and use it in GitHub Desktop.
This file contains 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
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