【问题标题】:read out random item from String Array in Swift 3从 Swift 3 中的字符串数组中读取随机项
【发布时间】:2018-07-22 20:57:45
【问题描述】:

我在 Swift 3 (Xcode) 中有一个 Strings 数组,我想从中读出 5 个随机的唯一元素。我正在尝试这样的事情:

class ViewController: UIViewController {

    @IBOutlet var Nr1: UILabel!
    @IBOutlet var Nr2: UILabel!
    @IBOutlet var Nr3: UILabel!
    @IBOutlet var Nr4: UILabel!
    @IBOutlet var Nr5: UILabel!

    myArray = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]

    func foo() {
        for index in 0..<6 {
            let randomNr = Int(arc4random_uniform(UInt32(myArray.count)))
            Nr+(index).text = String (randomNr)
        }
    }

}

但我不能将迭代索引作为占位符来获取Nr1.textNr2.textNr3.text等。

下一个问题是:我如何比较随机项目以使其独一无二?

有人可以帮我解决这个问题吗?

【问题讨论】:

  • 仅供参考 - 了解IBOutletCollection

标签: arrays swift loops iteration


【解决方案1】:

您可以尝试以下方法。

首先,添加 Fisher-Yates shuffle 的实现(来自 here),以便随机化数组中的元素。

extension MutableCollection {
    /// Shuffles the contents of this collection.
    mutating func shuffle() {
        let c = count
        guard c > 1 else { return }

        for (firstUnshuffled, unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1)) {
            let d: IndexDistance = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
            let i = index(firstUnshuffled, offsetBy: d)
            swapAt(firstUnshuffled, i)
        }
    }
}

extension Sequence {
    /// Returns an array with the contents of this sequence, shuffled.
    func shuffled() -> [Element] {
        var result = Array(self)
        result.shuffle()
        return result
    }
}

然后使用shuffled()方法对数组中的元素进行随机化,取前五个元素,放入标签中。

class ViewController: UIViewController {

    // ...

    let myArray = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]

    func foo() {
        // Take the array and shuffle it.
        let shuffled = self.myArray.shuffled()
        // Slice the first five elements.
        let randomElements = shuffled[0..<5]

        // Build an array that contains all the labels in order.
        let outlets = [self.nr1, self.nr2, self.nr3, self.nr4, self.nr5]
        // Loop through the randomly chosen elements, together with their indices.
        for (i, randomElement) in randomElements.enumerated() {
            // Put the random element at index `i` into the label at index `i`.
            outlets[i]?.text = randomElement
        }
    }

    // ...

}

您在问题中尝试按顺序访问每个IBOutlets 的操作将不起作用,因为您无法从变量内的值形成标识符。但是,您可以循环访问IBOutlets,如上所示。

附加说明:我已将UILabel 变量的名称从Nr1Nr2 等更改为nr1nr2 等。这是因为在Swift 中,UpperCamelCase 应该仅用于类型名称,变量等应使用lowerCamelCase命名。

【讨论】:

    【解决方案2】:

    我这样做的方法是将它们插入一个数组列表并产生一个介于 0 和列表大小之间的数字。使用此编号从列表中获取并删除该项目,然后重复此过程。每次尺寸都会变小,并且在获取它们时将它们移除,因此不可能得到非唯一的项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-22
      • 1970-01-01
      • 1970-01-01
      • 2012-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多