简体   繁体   English

Swift-生成不在检索列表中的随机数

[英]Swift - Generating random number that is not in retrieved list

I'm trying to retrieve a list from the user defaults, generate a random number that's not in this list, and append this number to the list and save it again. 我正在尝试从用户默认值中检索列表,生成不在此列表中的随机数,然后将此数字附加到列表中并再次保存。

My function looks like this: 我的函数如下所示:

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
}

and this return a list like this: 这将返回如下列表:

[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]

as the first list, and for every number being appended, it also adds 3 numbers before this number. 作为第一个列表,并且对于每个附加的数字,它还会在此数字之前添加3个数字。 Although no number repeats itself, this is not the result I was looking for, therefore I need to know if my function for creating this random number looks wrong. 尽管没有数字会重复,但这不是我想要的结果,因此我需要知道创建该随机数的函数是否出错。

Any suggestions on how to proceed would be appreciated. 任何建议如何进行将不胜感激。

Bear in mind, your user default will persist across runs of your program. 请记住,您的用户默认值将在程序运行期间持续存在。 Presumably you have (through previous attempts) managed to save a value of that list you give. 大概您已经(通过先前的尝试)设法保存了您提供的该列表的值。

Try pasting your code into a fresh Swift console app. 尝试将代码粘贴到新的Swift控制台应用程序中。 It will work correctly for up to 10 runs, then it will go into an infinite loop – because usedNumbersList will contain all 10 numbers possible already – so the while loop will never terminate. 它最多可以正常运行10次,然后进入无限循环-因为usedNumbersList已经包含了所有可能的10个数字-因此while循环永远不会终止。

Why you aren't getting the infinite loop in your code but rather the behaviour you describe is a bit mysterious. 为什么您的代码中没有出现无限循环,但您描述的行为却有些神秘。 The cause may be code outside the function you give in your question. 原因可能是您在问题中给出的功能之外的代码。 But it seems like you need to be able to detect this condition and handle it in some way. 但是似乎您需要能够检测到这种情况并以某种方式处理它。

By the way, you would probably find this code easier to debug if you split it into two functions, one that generated random numbers not in a given list: 顺便说一句,如果将它分成两个函数,可能会发现更容易调试该代码,其中一个函数生成不在给定列表中的随机数:

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
}

This way you can test your random-number-generating function independently (maybe try it out in a playground) from your fetching/saving code: 这样,您就可以从获取/保存代码中独立测试随机数生成函数(也许在操场上试用一下):

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)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM