You could use a Set to filter already extracted numbers (Sets contains unique elements), and do something like this
import Foundation
var setOfNumbers: Set<UInt32> = []
func extractUniqueNumber(with treshold: UInt32, alreadyExtracted: inout Set<UInt32>) -> UInt32? {
guard alreadyExtracted.count < treshold else { return nil }
let randomNumber = arc4random_uniform(treshold)
if !alreadyExtracted.contains(randomNumber) {
alreadyExtracted.insert(randomNumber)
return randomNumber
} else {
return extractUniqueNumber(with: treshold, alreadyExtracted: &alreadyExtracted)
}
}
// test it out with a number of tries
for _ in 0...100 {
if let number = extractUniqueNumber(with: 100, alreadyExtracted: &setOfNumbers) {
print("Your number is: \(number).\n- Previously extracted numbers) are: \(setOfNumbers)")
} else {
print("You have extracted all numbers already")
}
}
if the order in which numbers are extracted is important, the Set can be replaced with an Array. The price to pay would be a slower search for the already extracted number, but in the range of 100 would most likely be still fine. In this case the code would be
var setOfNumbers: [UInt32] = []
func extractUniqueNumber(with treshold: UInt32, alreadyExtracted: inout [UInt32]) -> UInt32? {
guard alreadyExtracted.count < treshold else { return nil }
let randomNumber = arc4random_uniform(treshold)
if !alreadyExtracted.contains(randomNumber) {
alreadyExtracted.append(randomNumber)
return randomNumber
} else {
return extractUniqueNumber(with: treshold, alreadyExtracted: &alreadyExtracted)
}
}