【问题标题】:Create a random number array without having a number repeat twice in a row创建一个随机数数组,没有一个数字连续重复两次
【发布时间】:2015-06-27 05:46:18
【问题描述】:

我对这一切都很陌生,所以我希望这是有道理的。我想在按下按钮时显示随机图像,而不会连续出现两次相同的图像。我在这个网站上找到了类似的问题,答案有帮助,但我的代码中仍然出现我不理解的错误。

这是我的图像数组的代码,位于类的顶部:

var imageArray:[String] = ["yes", "no", "indeed", "nope", "ofCourse", "noWay"]

这是我在按钮 IBAction 下用于随机数的代码:(这可能有我不知道的错误,就像我之前说的我是菜鸟)

 var currentNo: UInt32 = 0

    func randomNumber(maximum: UInt32) -> Int {

        var randomNumber: UInt32

        do {
            randomNumber = (arc4random_uniform(6))
        }while currentNo == randomNumber

        currentNo = randomNumber

        return Int(randomNumber)
    }
    var imageString:String = self.imageArray [randomNumber]

    self.iPhoneImage.image = UIImage(named: imageString)

我在这一行收到错误

var imageString:String = self.imageArray [randomNumber]

上面写着

"无法使用索引类型订阅 '[String]' 类型的值 '(UInt32) -> Int'

【问题讨论】:

  • 您正在调用没有参数的方法 - var imageString:String = self.imageArray [randomNumber]。
  • randomNumber 方法需要一个参数。

标签: arrays xcode swift


【解决方案1】:

如果您不希望随机项目重复,您可以将其删除并在下一次抽奖后将其添加回来,如下所示:

var imageArray: [String] = ["yes", "no", "indeed", "nope", "ofCourse", "noWay"]
var random: Int {
    return Int(arc4random_uniform(UInt32(imageArray.count)))
}
var lastImage = ""
var imageName: String {
    let newImage = imageArray.removeAtIndex(random)
    if lastImage != "" {
        imageArray.append(lastImage)
    }
    lastImage = newImage
    return newImage
}

测试

println(imageName)  // "ofCourse"
println(imageName)  // "no"
println(imageName)  // "yes"
println(imageName)  // "nope"
println(imageName)  // "indeed"
println(imageName)  // "noWay" 
println(imageName)  // "ofCourse"
println(imageName)  // "noWay
println(imageName)  // "nope"
println(imageName)  // "ofCourse"
println(imageName)  // "noWay"
println(imageName)  // "yes"
println(imageName)  // "ofCourse"
println(imageName)  // "indeed"
println(imageName)  // "yes"
println(imageName)  // "nope"
println(imageName)  // "noWay"
println(imageName)  // "no"
println(imageName)  // "noWay"

【讨论】:

  • 是的,这样就不会重复了。伟大的逻辑狮子座..:)
  • 我运行了你的代码并以 self.iPhoneImage.image = UIImage(named:imageName) 结束了它,但它仍然偶尔会连续两次使用同一个图像!知道发生了什么吗?
  • 我很确定您没有按原样运行我的代码。它删除了最后一个元素,因此无法重复
  • 是这样吗? var imageArray:[String] = ["yes", "no", "indeed", "nope", "ofCourse", "noWay"] var random:Int{ return Int(arc4random_uniform(UInt32(imageArray.count))) } var lastImage = "" var newImage = "" var imageName: String { newImage = imageArray.removeAtIndex(random) if lastImage != "" { imageArray.append(lastImage) } lastImage = newImage return newImage }
  • 完美运行!我把代码放在了错误的位置。谢谢!
【解决方案2】:

这样可以正常工作:

var imageString:String = self.imageArray[randomNumber(6)]

正如您在函数声明中看到的func randomNumber(maximum: UInt32) -> Int,这意味着您的函数接受maximum 类型的参数UInt32 并返回Int

但是您正在使用self.imageArray[randomNumber] 之类的函数,您想使用randomNumber 函数访问来自imageArray 的元素。

但是您的函数接受您未分配的参数,因此您可以以这种方式使用您的函数randomNumber(6),其中 6 是最大值。

您可以根据需要更改最大值。

【讨论】:

  • 谢谢!这消除了错误并运行,但仍有连续出现两次的图像。你知道问题可能是什么吗?
【解决方案3】:

使用GameKit 实际上有一个内置的随机分布,可以为您执行此操作,同时仍然是统一且相当随机的:

import GameplayKit

let imageArray = ["yes", "no", "indeed", "nope", "ofCourse", "noWay"]

let randomDistribution = GKShuffledDistribution(lowestValue: 0, highestValue: imageArray.count - 1)

func randomItem() -> String {
    return imageArray[randomDistribution.nextInt()]
}

我建议把它封装成它自己的类型:

struct RandomNonRepeating<Element> {
    let values : [Element]
    let distribution : GKRandomDistribution

    init(values : [Element]) {
        self.values = values
        distribution = GKShuffledDistribution(
            lowestValue: 0, highestValue: values.count - 1)
    }

    func next() -> Element {
        return values[distribution.nextInt()]
    }
}

可以这样使用:

let x = RandomNonRepeating(values: [1, 2, 3, 4, 5])

for _ in 0...30 {
    x.next()
}

给予

4
3
2
1
5
2
4
3
1
5
4
3
2
1
5
3
1
2
4
5
4
1
3
2
5
4
3
1
2
5
3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    相关资源
    最近更新 更多