Swift - 生成不在检索列表中的随机数
Swift - Generating random number that is not in retrieved list
我正在尝试从用户默认值中检索一个列表,生成一个不在此列表中的随机数,并将此数字附加到列表中并再次保存。
我的函数如下所示:
func createRandiAndSaveNumberToCell()->Double{
var defaults = NSUserDefaults.standardUserDefaults()
var numbersList: [Int] = []
if let firstNameIsNotNill = defaults.objectForKey("usedNumbersList") as? [Int] {
numbersList = defaults.objectForKey("usedNumbersList") as [Int]
}
var randomNumb = Int(arc4random_uniform(10))
while contains(numbersList, randomNumb){
randomNumb = Int(arc4random_uniform(10))
}
numbersList.append(randomNumb)
defaults.setObject(numbersList, forKey: "usedNumbersList")
var randi = Double(randomNumb)
println(numbersList)
return randi
}
而这个 return 列表如下:
[13, 26, 75, 35, 57, 23, 6, 0, 74, 69, 38, 30, 3, 29, 52, 62, 46, 42, 37, 55, 65, 9, 18, 49, 15, 40, 71, 20, 44, 67, 43, 21, 33, 59, 8, 1, 63, 68, 2, 5]
作为第一个列表,对于每个附加的数字,它还在该数字之前添加 3 个数字。
虽然没有数字重复,但这不是我要找的结果,因此我需要知道我创建这个随机数的函数是否看起来有问题。
如有任何关于如何进行的建议,我们将不胜感激。
请记住,您的用户默认设置将在您的程序运行期间保持不变。大概您已经(通过之前的尝试)设法保存了您提供的列表的值。
尝试将您的代码粘贴到新的 Swift 控制台应用程序中。它最多可以正确运行 10 次,然后进入无限循环——因为 usedNumbersList
已经包含了所有可能的 10 个数字——所以 while 循环永远不会终止。
为什么您的代码中没有出现无限循环,而是您描述的行为有点神秘。原因可能是您在问题中提供的功能之外的代码。但似乎您需要能够检测到这种情况并以某种方式处理它。
顺便说一句,如果将此代码拆分为两个函数,您可能会发现它更易于调试,其中一个生成不在给定列表中的随机数:
func randomNotIn(source: [Int], #upperBound: UInt32) -> Int {
// detect possible infinte loop
precondition(source.count < Int(upperBound))
// by making this a do…while, you can scrap the double-assignment:
var candidate: Int // you don’t _have_ to give a var a value
do {
// so long as the compiler can see it’s guaranteed to be
// assigned a value before it’s first used
candidate = Int(arc4random_uniform(upperBound))
} while contains(source, candidate)
return candidate
}
通过这种方式,您可以根据 fetching/saving 代码独立测试随机数生成函数(也许可以在操场上尝试):
func createRandiAndSaveNumberToCell() -> Double {
let defaults = NSUserDefaults.standardUserDefaults()
let usedKeyName = "usedNumbersList"
// this is an alternative to your if-let, which uses the “??” operator
// to supply an empty list when objectForKey returns nil:
let usedNumbersList = defaults.objectForKey(usedKeyName) as? [Int] ?? []
let newRandom = randomNotIn(usedNumbersList, upperBound: 10)
let newUsedNumbersList = usedNumbersList + [newRandom]
defaults.setObject(newUsedNumbersList, forKey: usedKeyName)
println(newUsedNumbersList)
return Double(newRandom)
}
我正在尝试从用户默认值中检索一个列表,生成一个不在此列表中的随机数,并将此数字附加到列表中并再次保存。
我的函数如下所示:
func createRandiAndSaveNumberToCell()->Double{
var defaults = NSUserDefaults.standardUserDefaults()
var numbersList: [Int] = []
if let firstNameIsNotNill = defaults.objectForKey("usedNumbersList") as? [Int] {
numbersList = defaults.objectForKey("usedNumbersList") as [Int]
}
var randomNumb = Int(arc4random_uniform(10))
while contains(numbersList, randomNumb){
randomNumb = Int(arc4random_uniform(10))
}
numbersList.append(randomNumb)
defaults.setObject(numbersList, forKey: "usedNumbersList")
var randi = Double(randomNumb)
println(numbersList)
return randi
}
而这个 return 列表如下:
[13, 26, 75, 35, 57, 23, 6, 0, 74, 69, 38, 30, 3, 29, 52, 62, 46, 42, 37, 55, 65, 9, 18, 49, 15, 40, 71, 20, 44, 67, 43, 21, 33, 59, 8, 1, 63, 68, 2, 5]
作为第一个列表,对于每个附加的数字,它还在该数字之前添加 3 个数字。 虽然没有数字重复,但这不是我要找的结果,因此我需要知道我创建这个随机数的函数是否看起来有问题。
如有任何关于如何进行的建议,我们将不胜感激。
请记住,您的用户默认设置将在您的程序运行期间保持不变。大概您已经(通过之前的尝试)设法保存了您提供的列表的值。
尝试将您的代码粘贴到新的 Swift 控制台应用程序中。它最多可以正确运行 10 次,然后进入无限循环——因为 usedNumbersList
已经包含了所有可能的 10 个数字——所以 while 循环永远不会终止。
为什么您的代码中没有出现无限循环,而是您描述的行为有点神秘。原因可能是您在问题中提供的功能之外的代码。但似乎您需要能够检测到这种情况并以某种方式处理它。
顺便说一句,如果将此代码拆分为两个函数,您可能会发现它更易于调试,其中一个生成不在给定列表中的随机数:
func randomNotIn(source: [Int], #upperBound: UInt32) -> Int {
// detect possible infinte loop
precondition(source.count < Int(upperBound))
// by making this a do…while, you can scrap the double-assignment:
var candidate: Int // you don’t _have_ to give a var a value
do {
// so long as the compiler can see it’s guaranteed to be
// assigned a value before it’s first used
candidate = Int(arc4random_uniform(upperBound))
} while contains(source, candidate)
return candidate
}
通过这种方式,您可以根据 fetching/saving 代码独立测试随机数生成函数(也许可以在操场上尝试):
func createRandiAndSaveNumberToCell() -> Double {
let defaults = NSUserDefaults.standardUserDefaults()
let usedKeyName = "usedNumbersList"
// this is an alternative to your if-let, which uses the “??” operator
// to supply an empty list when objectForKey returns nil:
let usedNumbersList = defaults.objectForKey(usedKeyName) as? [Int] ?? []
let newRandom = randomNotIn(usedNumbersList, upperBound: 10)
let newUsedNumbersList = usedNumbersList + [newRandom]
defaults.setObject(newUsedNumbersList, forKey: usedKeyName)
println(newUsedNumbersList)
return Double(newRandom)
}