如何在iOS中只获取一次随机数

时间:2018-04-21 12:42:05

标签: ios swift random

我想为iOS创建一个激励性的应用程序。使用此代码随机选择动机句子。

arc4random_uniform(100)

问题: 代码显示例如2和另外2,因此用户再次获得相同的句子。

我需要一些从一个范围获得一个随机数的东西,例如100只一次,每个数字之后代码应该重复一次,以便用户可以再次看到激励句子。

1 个答案:

答案 0 :(得分:1)

您可以使用Set来过滤已经提取的数字(集合包含唯一元素),并执行类似这样的操作

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

如果提取数字的顺序很重要,则可以用数组替换Set。要支付的价格是对已经提取的数字的较慢搜索,但在100的范围内很可能仍然很好。在这种情况下,代码将是

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