【问题标题】:Eliminating repeats in a switch statement w/ Swift in iOS在 iOS 中使用 Swift 消除 switch 语句中的重复
【发布时间】:2016-07-06 02:41:04
【问题描述】:

在我正在构建的这个小型练习应用程序中,背景应该每 0.25 秒保持一次颜色交替,因为它看起来真的很酷。然而,由于我使用的是“arc4random_uniform”函数,它偶尔会连续两次选择相同的案例,导致我不喜欢的相同颜色的持续时间很长。关于如何消除这些 switch 语句中的立即重复以便它连续两次选择相同的情况的任何想法?

    switch arc4random_uniform(10) {
    case 0:
        self.backgroundImage.backgroundColor = UIColor.redColor()
    case 1:
        self.backgroundImage.backgroundColor = UIColor.orangeColor()
    case 2:
        self.backgroundImage.backgroundColor = UIColor.yellowColor()
    case 3:
        self.backgroundImage.backgroundColor = UIColor.greenColor()
    case 4:
        self.backgroundImage.backgroundColor = UIColor.blueColor()
    case 5:
        self.backgroundImage.backgroundColor = UIColor.purpleColor()
    case 6:
        self.backgroundImage.backgroundColor = UIColor.blackColor()
    case 7:
        self.backgroundImage.backgroundColor = UIColor.whiteColor()
    case 8:
        self.backgroundImage.backgroundColor = UIColor.brownColor()
    case 9:
        self.backgroundImage.backgroundColor = UIColor.grayColor()
    case 10:
        self.backgroundImage.backgroundColor = UIColor.blackColor()

    default:
        self.backgroundImage.backgroundColor = UIColor.clearColor()

    break;

    }

【问题讨论】:

    标签: ios xcode swift switch-statement xcode7


    【解决方案1】:

    Eli 的答案会起作用,但在 while 循环中重新生成随机数会不必要地低效。相反,如果当前的随机数与前一个相同,我建议使用除以 10 时的余数来增加随机数,并在 switch 语句中使用该数,这样随机操作就不会不必要地重复,例如:

    var prevNum:UInt32 = 0
    
    func changeColor() {
        var randomNum = arc4random_uniform(10)
        if randomNum == prevNum {
            randomNum = (randomNum+1)%10
        }
        prevNum = randomNum
    
        // insert your switch statement here
    }
    

    理论上(尽管在实践中不太可能)Eli 的代码会导致无限循环。

    【讨论】:

    • 您的代码非常适合我!我根本没有重复! :)
    • 超过 2 次迭代的概率为 0.1%,无限次迭代的概率在数学上为 0。
    • @EliSadoff 我说的是理论上,不是数学上的。
    • 与哈希表开放寻址有一个巧妙的平行关系,对于任何C mod N != 0,它都可以是(x+C) mode N。同样,可以使用二次探测等。缺点是人类观察者可以知道白色比其他颜色更可能跟随黑色(基于 +1 mod N 和 OP 颜色列表的示例)。
    【解决方案2】:

    尝试使用之前的值存储一个变量,并且在您输入 switch 语句之前有一个 while 语句,您可以这样做

    var num = arc4random_uniform(10);
    while(num == prev) {
      num = arc4random_uniform(10);
    }
    

    然后进入你的 switch 语句。

    【讨论】:

    • 感谢您的回答,Eli!所以你是说我应该把它放在我的 switch 语句开始之前,然后使用 prev 变量来存储前一个案例#?
    • 是的!这正是我要说的。
    【解决方案3】:

    您可以通过创建一个数组然后对其进行洗牌来创建一个颜色循环。这样,数字就不能重复。然后你可以遍历数组并使用每个值一次。

    var numbers = [Int](0 ..< 10)
    
    for i in 0 ..< 10
    {
        let j = Int(arc4random_uniform(10))
        (numbers[i], numbers[j]) = (numbers[j], numbers[i])
    }
    

    为避免生成新数组时的重复,可以使用

    if numbers.first == oldNumbers.last
    {
        numbers.remove(at: 0)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-06
      • 2018-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多